{
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        ""
      ],
      "metadata": {
        "id": "fgJbeG8EGMCL"
      }
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Vzj98NRfoAd4"
      },
      "source": [
        "\n",
        "\n",
        "### LifeLong Machine Learning\n",
        "### TA's Slide\n",
        "[Slide](https://docs.google.com/presentation/d/1SMJLWPTPCIrZdNdAjrS4zQZx1kfB73jCFSb7JRX90gQ/edit?usp=sharing)\n",
        "\n",
        "### Definition\n",
        "The detailed explanations and definitions of LifeLong Learning please refer to [LifeLong learning](https://youtu.be/7qT5P9KJnWo) \n",
        "\n",
        "\n",
        "### Methods\n",
        "Someone proposed a survey paper for LifeLong Learning at the end of 2019 to distinguish 2016-2019 LigeLong Learning methods into three families.\n",
        "\n",
        "We can distinguish LifeLong Learning methods into three families, based on how task\n",
        "specific information is stored and used throughout the sequential learning process:\n",
        "* Replay-based methods\n",
        "* Regularization-based methods\n",
        "* Parameter isolation methods\n",
        "\n",
        "<img src=\"https://i.ibb.co/VDFJkWG/2019-12-29-17-25.png\" width=\"100%\">\n",
        "\n",
        "In this assignment, we have to go through EWC, MAS, SI, Remanian Walk, SCP Methods in the prior-focused methods of the regularization-based methods. \n",
        "\n",
        "Source: [Continual Learning in Neural\n",
        "Networks](https://arxiv.org/pdf/1910.02718.pdf)\n",
        "\n",
        "Please feel free to mail us if you have any questions.\n",
        "\n",
        "ntu-ml-2022spring-ta@googlegroups.com\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kdEFq3wqsCHB"
      },
      "source": [
        "# Utilities"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Import Libraries"
      ],
      "metadata": {
        "id": "w4Y8VK-lfnA0"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xbCbsCR0r1rQ"
      },
      "outputs": [],
      "source": [
        "import argparse\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "import os\n",
        "import torch\n",
        "import torch.utils.data as data\n",
        "from torch.utils.data import DataLoader\n",
        "import torch.utils.data.sampler as sampler\n",
        "import torch.nn as nn\n",
        "import torch.nn.functional as F\n",
        "import torchvision\n",
        "from torchvision import datasets, transforms\n",
        "import tqdm\n",
        "from tqdm import trange"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Check devices"
      ],
      "metadata": {
        "id": "eUz2RKk-ftcK"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "!nvidia-smi"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iZbpbUMINUBk",
        "outputId": "b4fe903a-00de-4b9d-a03c-0f7033d0cfb5"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Tue May 24 04:16:36 2022       \n",
            "+-----------------------------------------------------------------------------+\n",
            "| NVIDIA-SMI 460.32.03    Driver Version: 460.32.03    CUDA Version: 11.2     |\n",
            "|-------------------------------+----------------------+----------------------+\n",
            "| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |\n",
            "| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |\n",
            "|                               |                      |               MIG M. |\n",
            "|===============================+======================+======================|\n",
            "|   0  Tesla T4            Off  | 00000000:00:04.0 Off |                    0 |\n",
            "| N/A   36C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |\n",
            "|                               |                      |                  N/A |\n",
            "+-------------------------------+----------------------+----------------------+\n",
            "                                                                               \n",
            "+-----------------------------------------------------------------------------+\n",
            "| Processes:                                                                  |\n",
            "|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |\n",
            "|        ID   ID                                                   Usage      |\n",
            "|=============================================================================|\n",
            "|  No running processes found                                                 |\n",
            "+-----------------------------------------------------------------------------+\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "QZjNHdafsPlm"
      },
      "source": [
        "### Fix Random Seeds"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "MX0TGy3iriy8"
      },
      "outputs": [],
      "source": [
        "def same_seeds(seed):\n",
        "  torch.manual_seed(seed)\n",
        "  if torch.cuda.is_available():\n",
        "    torch.cuda.manual_seed(seed)\n",
        "    torch.cuda.manual_seed_all(seed)  \n",
        "  np.random.seed(seed)  \n",
        "  torch.backends.cudnn.benchmark = False\n",
        "  torch.backends.cudnn.deterministic = True\n",
        "\n",
        "same_seeds(0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-R-ocGK8sf_f"
      },
      "source": [
        "# Prepare Data\n",
        "We utilize rotated MNIST as our training dataset.\n",
        "\n",
        "So, first, we utilize 5 different rotations to generate 10 different rotated MNISTs as different tasks."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uvWzrg9qsrOr"
      },
      "source": [
        "### Rotation and Transformation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "XKzqghAlnvtN"
      },
      "outputs": [],
      "source": [
        "# Rotate MNIST to generate 10 tasks\n",
        "\n",
        "def _rotate_image(image, angle):\n",
        "  if angle is None:\n",
        "    return image\n",
        "\n",
        "  image = transforms.functional.rotate(image, angle=angle)\n",
        "  return image\n",
        "\n",
        "def get_transform(angle=None):\n",
        "  transform = transforms.Compose([transforms.ToTensor(),\n",
        "                   transforms.Lambda(lambda x: _rotate_image(x, angle)),\n",
        "                   Pad(28)\n",
        "                   ])\n",
        "  return transform\n",
        "\n",
        "class Pad(object):\n",
        "  def __init__(self, size, fill=0, padding_mode='constant'):\n",
        "    self.size = size\n",
        "    self.fill = fill\n",
        "    self.padding_mode = padding_mode\n",
        "    \n",
        "  def __call__(self, img):\n",
        "    # If the H and W of img is not equal to desired size,\n",
        "    # then pad the channel of img to desired size.\n",
        "    img_size = img.size()[1]\n",
        "    assert ((self.size - img_size) % 2 == 0)\n",
        "    padding = (self.size - img_size) // 2\n",
        "    padding = (padding, padding, padding, padding)\n",
        "    return F.pad(img, padding, self.padding_mode, self.fill)\n",
        "\n",
        "class Data():\n",
        "  def __init__(self, path, train=True, angle=None):\n",
        "    transform = get_transform(angle)\n",
        "    self.dataset = datasets.MNIST(root=os.path.join(path, \"MNIST\"), transform=transform, train=train, download=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LDEOJ436rs88"
      },
      "source": [
        "### Dataloaders and Arguments\n",
        "- Training Arguments\n",
        "- Setup 5 different Rotations\n",
        "- 5 Train DataLoader\n",
        "- 5 Test DataLoader "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "cD2GEHlOrNQ2",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 435,
          "referenced_widgets": [
            "6678e54bfcce4aaa80134cf29d543bce",
            "d6b498ee01f74b12a51dc944e633c304",
            "e4c801c7dea848b8b392808ba94acc07",
            "954f009683e34fa2871775d8eebea8ba",
            "afe49763962c4bc293ba8692feaf8078",
            "7c9171136dcc426baaddb573f587a200",
            "74e98976de5b465a8218a4f5398d89ee",
            "3c57de7448674f718a2c12f7a8a3dc73",
            "bd3b7a2948c6460db33ecebebacb3e6e",
            "262e84a4c30448a89f9a4fcb09d718d4",
            "342d7362bdc242919b28d8d389b5ed2c",
            "5bf7bd4c4ac047b382f0d85a558704b1",
            "557c67df0db540a0b0597d1ba64fe2c7",
            "a863f04a60404ece8e3492705d56082d",
            "019c9ffd1526488887944f9d3d3ac559",
            "21bf55b0dad04eb3baa460994dfffa2e",
            "d71a16db1bd043cba776108b5b2024a5",
            "bb2e25bff7c84ab0b613b9bfa4d9a3bf",
            "6bfe7158ed774e70ab3e93c985208b02",
            "a3a8cdd6807d4c2c90af0cfb1708fefb",
            "ed01d150ab1946b9b26ebfc1028ce74c",
            "8059df5c69ad48af8627f7bae3cb1c14",
            "49683c778d6d4b2b8eef56ff767d1a5f",
            "cd204aebd36c4a51b9a3e076813c22f5",
            "a4b5d00ba1394ee3a84a6b0482392250",
            "9574e0c85a9b4fbc8d5688297e75c4de",
            "b73534bd79204873a0363689e54546c1",
            "bbf27d4324d84ea182524b00685141bc",
            "b53d43d75e34457fab24ee729e816c2b",
            "489df34a47d64f5e8069c06d26d1e9cc",
            "cb1dd9f39ad543698a883694d737d62d",
            "adb1230c890a4d099c71ef949c3933a5",
            "9e3719f2f271462e98808d4aa595e3db",
            "4c0f433640d84267ad7d429eba7822a9",
            "e508442a7aa34b358b9970ae313a26f8",
            "a52e3522bb854861a370e5ddf6f52bc2",
            "87a4cd167a794115998e6505f6dabc44",
            "8c77c242a7c1474b9e2758291c57dd44",
            "9514e4e67c7b4ac28bd4e0f513027d9f",
            "5cea3374e02547308903a5b30776911b",
            "74232ccdd40247378f4173e6bd6d306e",
            "71ecc787a84641b1ae638ca713d61ffc",
            "988647e20dbd45d9b6dfce4a7a06ffbd",
            "fead6467c43340a48571fa8d5f3d61d1"
          ]
        },
        "outputId": "8677d90b-61b0-4d15-aa8c-e4e11e583b0c"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz to data/MNIST/MNIST/raw/train-images-idx3-ubyte.gz\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/9912422 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "6678e54bfcce4aaa80134cf29d543bce"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Extracting data/MNIST/MNIST/raw/train-images-idx3-ubyte.gz to data/MNIST/MNIST/raw\n",
            "\n",
            "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz to data/MNIST/MNIST/raw/train-labels-idx1-ubyte.gz\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/28881 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "5bf7bd4c4ac047b382f0d85a558704b1"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Extracting data/MNIST/MNIST/raw/train-labels-idx1-ubyte.gz to data/MNIST/MNIST/raw\n",
            "\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to data/MNIST/MNIST/raw/t10k-images-idx3-ubyte.gz\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/1648877 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "49683c778d6d4b2b8eef56ff767d1a5f"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Extracting data/MNIST/MNIST/raw/t10k-images-idx3-ubyte.gz to data/MNIST/MNIST/raw\n",
            "\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n",
            "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to data/MNIST/MNIST/raw/t10k-labels-idx1-ubyte.gz\n"
          ]
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "  0%|          | 0/4542 [00:00<?, ?it/s]"
            ],
            "application/vnd.jupyter.widget-view+json": {
              "version_major": 2,
              "version_minor": 0,
              "model_id": "4c0f433640d84267ad7d429eba7822a9"
            }
          },
          "metadata": {}
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Extracting data/MNIST/MNIST/raw/t10k-labels-idx1-ubyte.gz to data/MNIST/MNIST/raw\n",
            "\n"
          ]
        }
      ],
      "source": [
        "class Args:\n",
        "  task_number = 5\n",
        "  epochs_per_task = 10\n",
        "  lr = 1.0e-4\n",
        "  batch_size = 128\n",
        "  test_size=8192\n",
        "\n",
        "args=Args()\n",
        "\n",
        "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
        "# generate rotations for the tasks.\n",
        "\n",
        "# generate rotated MNIST data from 10 different rotations.\n",
        "\n",
        "angle_list = [20 * x for x in range(args.task_number)]\n",
        "\n",
        "# prepare rotated MNIST datasets.\n",
        "\n",
        "train_datasets = [Data('data', angle=angle_list[index]) for index in range(args.task_number)]\n",
        "train_dataloaders = [DataLoader(data.dataset, batch_size=args.batch_size, shuffle=True) for data in train_datasets]\n",
        "\n",
        "test_datasets = [Data('data', train=False, angle=angle_list[index]) for index in range(args.task_number)]\n",
        "test_dataloaders = [DataLoader(data.dataset, batch_size=args.test_size, shuffle=True) for data in test_datasets]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4xBPkbzbvT_c"
      },
      "source": [
        "### Visualization"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 488
        },
        "id": "tNcH1lTKvgm9",
        "outputId": "81ecf17d-6e45-4f61-e328-1aba47663920"
      },
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<Figure size 2160x720 with 50 Axes>"
            ],
            "image/png": "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iFFet0E74ogjbH7hhRdsDl/S77Y+W7dunc3htiZu67MjjzzS5rlz53rjaIeCXOvZs6fN1157rbcvVbsft86BTDVq1Mhmt+aOOuoob1yzZs3SOt7uu+9uc58+fYo3OeSdpk2betvua96ZZ55ps9vqUfIvp3dfC6N4/XNboT7wwAPevquvvtrmgoKCYj8WSobbNk/y3+e99NJLJT2dyBx++OE2z549O8aZIE4NGjSwuXLlyt6+Vq1a2dy6dWuba9eu7Y07/fTTizWHZcuWedv33XefzaeddprN7ucvSfrkk09spm0vwurWrettd+zYMa37ufX49ttvRzonAMh34bZl4Tbn26xZs8bbPuaYY2w+9NBDbQ6346UlJfAbrqwBAAAAAAAAAACIESdrAAAAAAAAAAAAYlTm26BVr17d5kMOOcTb9+STT9rsttwpyhdffGHzHXfc4e175plnbH7vvfdsHjBggDfutttuS+uxgGw1bNjQ5qpVq8Y4E+ST/fbbz2a3rZMkde/e3eZq1arZbIzxxi1dutRmt63J/vvv740766yzbB45cqTNCxYsyHTayEPh36PptjgpKeedd563/cgjj9jsvj9A6dauXTtve5999rG5rLVBc1sCNm7c2Gb3/YL0+9ds5I8WLVp422+99ZbN4RbQueS2oAx/Rlq/fr3NY8eOtXnFihXeOLeFSrhNCsqnJk2a2PzUU095+1K9rnXp0sXbnjBhQvQTA4qpb9++3rbbttL9/OR+FgtzPz+FWwkDhXFbl4dbkoffO27jvg5LfrtV19ChQ73tAw44wGb39Xr58uXeuHDLVsDVsmVLb7tHjx42t23b1uaiXgP79etn8zfffOPtc9sCu+cSZs2alflkI8CVNQAAAAAAAAAAADHiZA0AAAAAAAAAAECMOFkDAAAAAAAAAAAQozK/Zs2//vUvm7t161bs47nr3tSoUcPbN336dJvdPufNmzcv9uMC29O+fXubr7zyypTj3J61nTp1svm7777LzcRQpoT71t9+++02d+3a1eaaNWumdTx3nS9JOuGEE2yuVKmSzeG1aHbZZZdCMyBJU6dO9bZTrVnz/fffe9vu2jHuGh7uGgphrVq1stntd4v8F1576P33349pJsXnrs148cUX2+z2XJZYFyyfff311972qlWrbI5izRq3Z/fatWu9fcccc4zNmzdvtnnMmDHFflxAks4991ybw+skTJo0yebLLrvM5vB6CEBJCr+ndNcIcfeddtpp3rhUazAFQZDysdw19+bPn+/tc9cLAbY59thjbe7Vq1da99m0aZO37b7HdI933XXXpTyGW8ePPfaYt8993wJI/t+nhg8f7u1z/4bkvm5OmzbNG1evXj2b77zzzpSP5R7Dvc/ZZ5+d/oQjxJU1AAAAAAAAAAAAMeJkDQAAAAAAAAAAQIzKZBu0Qw891OaTTz7Z5lSXjEp+C7OJEyd6+4YNG2bzN998Y/NHH33kjVuzZo3N7mV+RT0ukK3WrVt726NHj7a5qHYW7qV9S5YsiX5iKNPCl9pfdNFFGR9j0aJFNh9//PHevqVLl9q89957Z3xsQJJGjRrlbY8fP77Qcb/88ou3/e2332b8WLVq1bL5008/9fbVr1+/0PuE5zNnzpyMHxfxc1vllXUPP/xwoV8Pt6pE/lq9erW33b9/f5vdtriS/xnnvvvuS3nMjz/+2Gb39/2GDRu8cU2bNrX5qquuSnPGQNFmzpxpc4sWLWxevHixN+6aa66xmdZnyAW31ejTTz/t7fvjH/9Y6H3Cn9d33HFHm92/H3344YfeOLctf7rc9zPu4wCugQMH2uy+Rwh7/PHHbV65cqXN7t9Nw/vc1+gpU6Z449x2Ve59nn/++TRmjXy3ww7+aYnDDjvM5oceesjm6tWre+PeeecdmwcPHmzzjBkzvHFVqlSxedy4cTZ36NAh5ZxKw2f7/PmUCgAAAAAAAAAAUAZxsgYAAAAAAAAAACBGnKwBAAAAAAAAAACIUZlYs8btfyhJU6dOtdntNR8EgTdu8uTJNnfr1s3mtm3beuMGDBhgs9vz2+2nKEmffPKJzVu3brXZXTdH8vuMzp07V0A2zj//fG871doJ06ZN87afeOKJXE0JeeDMM89Ma1y4H/js2bNtvvbaa21216gJ23///TObHJD066+/ettF1VlxnXDCCTbXqVMnrfssW7bM2960aVOkc0LuNG/e3ObddtstxplEK9Vadu57ZpQv7tpab731lrdv3bp1Nh900EE29+rVyxvn9qcPr1Pjmjdvns2XXHJJ5pMFJHXu3Nnbbtmypc3u5/znnnvOG7dx48bcTgzlTvv27b1td92Evfbaq9jHP+CAA2z+4YcfvH3u+h7u5393/VpJ2nPPPQs99vz584s9P+Qndz2jatWq2Rxe5/jvf/+7zStWrEh5PHd92htuuMHmevXqeePc9w/uujm8dkOSevTo4W2nWocz/Jmma9euNhcUFKQ8vjuuqHVq3M/37rpNceHKGgAAAAAAAAAAgBhxsgYAAAAAAAAAACBGpbYNWpMmTWzu37+/t89t9eBeNhq+RM+9dGn9+vU2v/rqq9648Ham3EsIJalv3742d+/evVjHRvniXvZ84YUXevvc1ntr1661+ZZbbsn9xJA3Lr74Ym/bbVfy+uuv2/zll196477//vuMHyufWgwhv5x99tk2u/9PhH+fp3LTTTdFPieUjI4dO9qc7vNdGoVfXxs3blzouOXLl5fEdFDKFdUe4scff0y5z319fPbZZ21235MCxVG7dm2bjz766LTus2bNGm873Jo0HVdddZXNRbW16tevX8bHRtn3t7/9zdtOt/WZ2xbXbRstSR988IHNCxcuTHmMVatW2ezWaaq2Z5Lfvvrcc89Na64of55//nmbTzzxRJvdtnySNHToUJt79+5tc7jl7t13322zuzTE6tWrvXG33nqrzaNGjcp02shDgwcPttltoSf5bU9Hjhxps7t8iVT0e1uX29avKH369LE5vCRKHLiyBgAAAAAAAAAAIEacrAEAAAAAAAAAAIhRqWmDVqVKFW972LBhNrstKyRp3bp1Np933nk2z5kzxxsXV3uLBg0axPK4KJsaNWpk8wsvvJDWfUaMGGHz22+/HfWUkMe++eYbb3vgwIE5e6yjjjoqZ8cGtsdtQ3rdddd5+/bee2+bK1WqlNbxPv74Y5t/+eWXYs4Ocdl3331T7ps3b14JzqR43PfJkt8W7fPPP7fZfc8MFMZ9H3DooYd6+9q2bWtz+/btbXbbpgLFsWXLFpvD9Vehwm//rtRtvffOO++kdexrrrkm5b4rr7zS5oYNG6Yc57Y3D7ehos1kfunQoYPNRx55ZNr3+/rrr212W5C99957xZ5TUa3PXBMmTLDZXSYAcLmfZdy2fOE2aMcee6zNxx9/vM333HOPNy7V3z0HDRrkbbt/u0L5FG4h7rY+27x5s7dvypQpNrvtJH/++eeUx69atarN7mu55NepMcbm8HIS7utoacCVNQAAAAAAAAAAADHiZA0AAAAAAAAAAECMOFkDAAAAAAAAAAAQo1KzZs3BBx/sbYfXqXF17tzZ5unTp+dsTkBJOPHEE21u3rx5ynFvvvmmzcOHD8/pnICwPn362LzjjjumdZ8DDzww5b6ZM2fa/P7772c/MeQldy0vye8B7q6bUJTWrVvbHARBWvcpKCjwtt21biZNmmRzUT1zUXbNnj077imoVq1a3rb7HqFHjx42h/sxuwYPHmzz2rVrI5wd8tGGDRtsvvjii719c+fOtfmhhx6yObxeortu6P33329zuq+9KL/cdZGOPvpob5+7To27LkhRa3K0aNEi5fFOOeWUQu/j/j8gScuWLbPZXefs+eef98adffbZNi9ZsiTlnFA2uOsTVa9ePeU49zOM5K/Pkc06NXXq1PG23d/7bdq0SWse7ntUIJVNmzbZHP7M46pfv77N7prK7nofkv87/pFHHrF5/PjxxZon8kPt2rVt7t27t7fPrR13jRpJOvXUU9M6vrsG7dixY20Or3/ncn+P33HHHWk9Tly4sgYAAAAAAAAAACBGnKwBAAAAAAAAAACIUalpg3b33Xd72+4lduFWZ6Wh9VmFCr+d53Iv0Qa2J3xZ39ChQwsdN2PGDG/7/PPPt/nHH3+MfmIol9zL/A844ACb//GPf3jjUrWmdF8LpdSvh9988423fcEFF9i8ZcuW9CaLvNasWTObX375ZW9fgwYNSmQO7777rrf94IMPlsjjonSoW7duxvc56KCDvG33/avbsm/PPff0xlWuXNnm7t272xx+TXVb7s2aNctmt5WFJO2ww29v6T/88MO05g6ELVq0yNvu2bOnzaNHj7bZbU0Z3nZbpT7xxBPeuBUrVkQxTZRhNWvW9LYbN26ccqz73nHMmDE2f/nll964Jk2a2Ny/f3+b3dbpkt8+7fXXX7f5rrvu8sbttNNONr/11luFfh35x33Pt8suu3j73M/e55xzjrfv22+/LdbjXnbZZd6228rUNW/ePG/7rLPOimwOKH+iaN3ott8bNmyYzUuXLi32sVH2uZ91wq+pLrfdviTtuuuuNrt/Mwq3MnX/dlCjRg2bwy143e0nn3zS5nAL1NKGK2sAAAAAAAAAAABixMkaAAAAAAAAAACAGMXaBq1Tp042t2jRwtvnXqoUbodSGritfsKXWX388cclPR2Uco0aNbL5hRdeSOs+X331lbf93XffRTkllCOVKlWy+eCDD/b2ufW4++672+y23pH8VhTvv/++zSeeeKI3zm2r5nJb9EhSly5dbB4+fLjNmzdvLvT+KF/cVlKFbacjm3al7vsSSTrppJNsnjx5csZzQOnjvraF37898MADNt9www1pHa958+betlurv/76q80//fSTN27+/Pk2P/roozbPmTPHG+e2/nXfByxbtswbV61aNZsXLFiQ1tyB7XnppZds/uKLL2wOt68+7rjjbB4yZIjNDRs29MbdeuutNi9fvjyyeaLsaN26tbd9zz33pBz70EMP2XzzzTfbvNtuu3nj3PY7btvedevWeePGjRtnc79+/WzeZ599vHHu7wL3GG+++aY3Loo2Qig93M9E6X5ez9af//xnm2+66aaU49z3EW5dSrQ+Q+YqVqxo89FHH21zup+zXn31VW/brWMgzP27zsqVK7199erVs/l///ufty/8+SwV9+9TBQUFNrt/05L8FqgTJ05M69ilAVfWAAAAAAAAAAAAxIiTNQAAAAAAAAAAADHiZA0AAAAAAAAAAECMYl2zxu2vXblyZW/f999/b/Ozzz5bYnNyValSxdseOHBgoePeeustb/v666/P1ZRQRl177bU2p7t2wtChQ3M1HeS58Oupu67Miy++mPJ+gwYNsjn8uvbee+/ZXLdu3ZTjmjVrVuix3b6kknTbbbfZ/PXXX9s8fvx4b9ymTZtSzhf55dNPP7W5Xbt23r4ePXrYPGXKFJs3btyY1WP16tXL5iuvvDKrY6Bs6t27t83h9QZatWqV8fHc1y/Jfw377LPPbP7ggw8yPnbYJZdcYnP4NTW8zh0QNfc1+qyzzvL2uX3rR48ebfOll17qjXPXBjn++OOjniLKgPA6X0Vx16lxhd/LtmzZstBxnTt39rbdNcCOPPJIm2fMmJFyDvfee6/N7jo3QHG47xWKWp+hT58+Nj/44IM5nRPy3zPPPGOzu35sumuEpDsOkKS1a9fafOqpp3r7XnnlFZvdvy1J0qJFi2yeMGGCzY899pg3bvXq1Ta7tR1es8bdV5ZwZQ0AAAAAAAAAAECMOFkDAAAAAAAAAAAQo1jboBXFbX2zYsWKEntct/XZgAEDvH39+/e3edmyZTbfdddd3rj169fnaHYoS1q0aGFzhw4d0rqPe5nfwoULI58T8lelSpVsdtuZSf5rV9jkyZNtHjFihM3uZauS33Jn0qRJNh944IHeuM2bN9t8xx132Bxuj+a2phg7dqzNb7zxhjfu9ttvt3nNmjUpvgvp448/TrkPZU+4PdWtt94a6fHdtqa0QSu/3NeXsuC4445Lue+FF14owZmgvAu/RxgzZozNDz/8sM077OB/1GzTpo3NbrvLadOmRTtBlFq1a9f2to0xNrufg8Lcz1WNGjVKeYy+ffva7LY9k6QmTZrY/NRTTxV6//Ax3DZoQHEMGTLE5goVfvs300W1SA/XMLA99evXt/mCCy7w9p1++uk2uy3N5s6d64375JNPCj3GrrvuGtk8Ub7MmjXL2w63c86G+56ybdu2NodfU8tqq2iurAEAAAAAAAAAAIgRJ2sAAAAAAAAAALIBc/kAACAASURBVABiVGrboL388ssl9ljuZdVuu6CuXbt649xLs91LCIHCvP766zbXqVMn5bgPPvjA5p49e+ZySsgzFStWtHnw4ME29+vXzxu3YcMGm6+77jpv3zPPPGOz29bksMMO88b985//tPnggw+2+YsvvvDGXX755Ta//fbbNteqVcsb16pVK5u7d+9u8ymnnOKNmzp1qlJZunSpzY0bN045Dgg74YQT4p4CEKmXXnop7ikgzzVv3tzmM844w9t3+OGH2xxufeaaP3++ze+8806Es0NZ5bbicXNRwi1O3Pu5dfr1119746pWrWrz//73P5uPPvpob9yPP/6Y1jyAolSuXNnbdj8/uTUcrvurrrrK5vDnLGB73Ja5N998c8px7pIP7ud8STr11FNtdtugub/DgbhVq1bN5qJeU92/d5UlXFkDAAAAAAAAAAAQI07WAAAAAAAAAAAAxIiTNQAAAAAAAAAAADGKdc0aY0yhWfL7JLp9O6NwzTXXeNs33nijzTvttJPNY8eO9cadd955kc4D+W3nnXe2Odxb2TVy5Eib169fn9M5Ib9ccsklNrvr1Pz000/euEsvvdRmdy0lSTryyCNtdnvSnnTSSd44tyeo2/929OjR3jh3HRlXQUGBt/3aa68Vmrt16+aNO+eccwo9nvT713KUfpUqVbK5Q4cO3r633nrL5p9//jnSx3VrW5KGDx8e6fEBIB/su+++3vYVV1xhc5cuXWz+wx/+kNbxtmzZ4m2vWLHC5qLeGyN/uWvASv56sZ07d/b2ue9R3TVma9asmfL47uf18N8XfvjhB5sHDhxo8/Lly7czayA91atXt7lHjx7evuOPP77Q+zz99NPetvs3KF4nsT3t2rXztu+7776UY921Yd944w2bw7/Tb7rppkLvv3jx4swnCOTIlClT4p5CTnFlDQAAAAAAAAAAQIw4WQMAAAAAAAAAABCjWNugBUFQaJb8S/HCl/I9+uijNq9atcpm91JpSTr33HNtPuigg2zec889vXFff/21ze6lVG57KmB7wu2gKlRI71zozJkzczEdlAOpLlGuWLGit+22mHDbPkjS3nvvndZjufe77bbbbA63OCmucCuA8DbKntatW9v897//3eZwO4jGjRvbnKqd3vbUrVvX5o4dO9p89913e+PcNhWucPu1jRs3ZjUPINfC7X2aNGli8wcffFDS00EZ437OctuPum3PJKlRo0YZH3vOnDk233rrrd6+l19+OePjIb/88ssv3rbbujf8u/m9996zOfy3gnSsW7fO2x43bpzNkydPzvh4QGHctnwPPfSQzWeccUbK+7itnP/5z396+2h9hkyEP0+5yzpMnz7d2/fKK6/Y7Lam7tSpU8pjuO83V65cWbzJAhE64YQT4p5CTnFlDQAAAAAAAAAAQIw4WQMAAAAAAAAAABCjWNugFcVt49O7d29v3+mnn25zQUGBzfvss09axw63nXr77bdtTtVWCChMixYtbG7fvr23z72EefPmzTbff//93rjvvvsuR7NDvvv2229trlevns1VqlTxxrltIMMmTZpk8zvvvGPz+PHjvXGLFy+2OerWZ8hvbnuHZs2apRz3t7/9zeZw65J0ua0ADjnkEJuLap8ybdo0m0eNGuXtc98fAKVJuKbTbb2K8mO33Xaz+YADDvD2ua/L++23X8bHnjVrlrd955132jxhwgSbaeeDsA8//NDbdtvw/fWvf/X2tWvXLq1jPv744zb/97//tfmjjz7yxoVbAgFR2GOPPWwuqvXZokWLbA63+QeyFf49W9RSE27rs1NPPdXm4cOHe+PWrFlj88MPP2xz+HMSEKc//vGPcU8hp/hkBwAAAAAAAAAAECNO1gAAAAAAAAAAAMSIkzUAAAAAAAAAAAAxinXNmvfff9/m2bNne/sOP/zwlPf7wx/+YLPbjzls1apVNj/zzDM2X3XVVRnNE0ildu3aNrt1GbZ8+XKb+/Xrl9M5ofxo06aNzW7fWXetDkn6/vvvbX700Ue9fW5PWndtJaCkXX755Tk7tvv/gCRNnDjRZvc9wcaNG3M2ByCXjjrqKJsfe+yx+CaCElW3bl2b//Wvf3n73HUVs+3r7a7zedddd9k8ZcoUb9zPP/+c1fGBV199tdAMlFbhdb769u1b6LjPP//c2z7ppJNyNieUX7vuumvKfStXrvS2p06davPRRx+d8n4XXHCBze5nJqA0effdd2121+7Ml/USubIGAAAAAAAAAAAgRpysAQAAAAAAAAAAiFGsbdCWLVtmc5cuXbx9l156qc0DBgxI63jDhw/3tkeNGmXzl19+mc0UAaDUWrdunc1jxowpNANx69mzp81XXnmlzeeff36xj71o0SJv+6effrLZvTT6wQcf9MZ9+umnxX5sIE7GmLingBLSsmVLb7t///42H3HEETbvscceWR3ffd287777vH1DhgyxecOGDVkdHwDyyY033uhtd+3atdBxI0aM8LaXLFmSszmh/Prss89S7jvjjDO8bfe94+rVq22+//77vXFvvPFGRLMDcsf9PP/FF1/YHG79+3//9382h1sDlmZcWQMAAAAAAAAAABAjTtYAAAAAAAAAAADEiJM1AAAAAAAAAAAAMYp1zRrXihUrvO2BAwcWmoHSZMGCBTbPnDnT29e6deuSng4AlDoff/yxzb1797b53//+tzfulltusblOnTrevvHjx9s8depUmydMmOCN+/bbb4s3WaAUmzx5ss1nnnlmjDNBSTrttNOK3E5l/vz5Nr/yyivevl9//dXmu+66y+a1a9dmM0UAyGtNmza1uVatWinHuWskvvXWWzmdEyBJjz/+uLdduXJlm8PrK82ZM8fml19+2eZ77rknR7MDSoa7xuLDDz/s7bv11lttdtfPdd8nl0ZcWQMAAAAAAAAAABAjTtYAAAAAAAAAAADEyARBkP5gY9IfjMgEQWDinkNZQp3G5sMgCA6LexJlBXUaG+o0A9RpbKjTDFGr8eA9amao09jwmpoB6jQ21GkGSrJOb7/9dpv79u3r7VuyZInNHTt2tHnhwoW5n1g8qNMM8ZoaD96jZqYs16nbnnLcuHHevvbt29v84osv2nzBBRd44zZs2JCj2W1Xoa+pXFkDAAAAAAAAAAAQI07WAAAAAAAAAAAAxGiHuCcAAAAAAAAAlDavv/66zeE2aH/9619tzuPWZwBQahUUFNh81llneftuvfVWmy+//HKbBw4c6I2bP39+biaXJa6sAQAAAAAAAAAAiBEnawAAAAAA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Hj3a5p122inluCeeeKIkpoM8tN9++3nbV199dVr3c9dDcNdJ2nvvvaOZGModt8+sJD333HM2X3PNNWkdY+jQod62+3v7xhtvtLlWrVreuE8//dTm+vXrpzz+smXLCj1GQUFBWvMDolTU+4KpU6favNdee9m8dOnSnM4J8WrQoIHNlStX9vbNmDHDZvf9ZVFmzZrlba9du9bm/v3723zVVVdlNE8gHe46CZL01FNPFTrOrXtJWr58ec7mBGRr3Lhx3vZpp50W6fHnz59v8y677GLzDz/8EOnjoOxq1qyZt92nT59Cx7Vv397bdtfpPP/8821u0aKFN85d98b9m+3AgQO9cRs3bkxvwoCkli1bFvr18N8Opk2bZnPnzp1tDr/2dujQwWb3s/3jjz9enGnmHFfWAAAAAAAAAAAAxIiTNQAAAAAAAAAAADEqE23Q/vWvf3nb3bp1K3TcO++8421PnDjR5mHDhtk8cuRIb1y4Ldo2FStW9La3bNlicxAENocvxQYy0bp160K/XqFC6nOpb775ps3HHXdc5HNC/nr//fe97Zo1axY6btGiRd728ccfX+i4L7/80tt2L/F/6aWXbHYvU5Wkdu3a2ey2akH5cdttt3nbHTt2TDn2+++/t/mRRx6x2W11VpRw27K+ffva/Oijj9pcrVo1b9wVV1xh80033ZTWY6F0S/UaVRa0atXK5hUrVnj7Zs6caXPDhg1LbE6I18cff2xzUW3y0hX+Xb9hwwab3fYTl1xySbEfCwg799xzvW33M/akSZNsjrrtmft3Aknq169fpMdHfmvbtq3Nbtup008/3Rv34Ycf2uy29Q+39nHb87otLPfcc09v3D777JPljFFeHHvssd52r169Ch0Xfg0Mb2+zfv16b3v69Ok2u8tEVK1aNaN5onzr2rWrtz18+HCb3RaP4XZ97t+QqlSpYnO4harbBm2PPfaw2f1cJUkTJkzIZNo5x5U1AAAAAAAAAAAAMeJkDQAAAAAAAAAAQIw4WQMAAAAAAAAAABCjMrFmzb333uttn3zyyTa7/ZndvsqS9NBDD9n8+eef2/zqq69GPUUga26vxddee83mnj17euPWrl1r8y233JLzeaHsCvetv/32221OtUZN2Ny5c71tY0xa99ttt93SGgdMnTrV23bXrGncuHHK+/3yyy8ZP9bZZ5/tbV988cU2h9epcbnrQWTzuCgd2rRpY3OXLl1sLmtr1rivr+HXWvd97rp160psTih5LVq0sHnVqlU2F7VmTZ8+fbzt++67r9Bxp5xyirf99NNP2zxv3ryM5glkKrwO5+bNm23ef//9bQ6v3bFs2bK0jn/VVVfZvNdee9l8zTXXeOPcde3cx9phB/9PJ0uWLEnrcZFfvv7665T73Ndhd41jyV+T6YcffrDZfR2X/DoN17rLXV/BPR6wTd26db3tjRs32uyuKxP+e+vKlSsLPd7dd9/tbbt/l129erXN99xzT+aTRbkV/l1avXr1Qse5635J/mdzN//9739P63FL2xo1YVxZAwAAAAAAAAAAECNO1gAAAAAAAAAAAMSoTLRBC7dKqVWrls3u5aWPP/64N279+vU2R936zG0J1KpVK2/fu+++a/PRRx8d6eMi/+yyyy42X3jhhTZv3brVGzdixAibm/+r9AAAIABJREFU33777dxPDGXWjz/+6G1/8MEHNl900UUp77d48WKbu3XrltVjH3XUUYV+febMmd72+++/b3PFihVt3rJlS1aPi7LHfU2TpFGjRtn866+/RvpYo0eP9rYrVapU6LjevXt725MmTbJ55513tjndlisoHdq1a2ez+xo1ZswYb5zboqQ0GjZsWMp9gwcPttltSzF27Niczgklz23PuM8++9h86qmneuM6depk88iRI719Bx10kM29evWy2W0RKUnPPvuszeH3pUDUWrZs6W27n/Ofe+45m9P9HRxub3bllVfa3LBhQ5sXLlzojdt3331tdltehceddNJJNtMSLb/svvvu3rbbErJ+/fppHePII4/0tsP1k0qq1mfhz1Lue1S3heCbb76Z1uMg/+24447ettv62X3NGjp0qDfO/TzktvZz31+GDRo0KOt5ovxx24q6y0KEuecCCgoK0jp2gwYNvG33b/dlaTkJrqwBAAAAAAAAAACIESdrAAAAAAAAAAAAYlRq26C1aNHCZvfSO0n64YcfbF6xYoXNbqufXHBb9biXZYfb9rjtCYCwRo0aedsvvPCCzW7tuP8PSH67Pff/iXDLKyDszDPPtDl86efrr79u85dffpnxsa+//npv2z3G3LlzbW7cuLE3zv3/YNGiRRk/LvJPFK3PunfvXujXU7U9Cwtf3v/ggw8We06I380332zzeeedF+NMts9t9StJJ554os3u7/5169Z549xWwM2aNcvR7FCajR8/3tt+6623bHY/t0ip3zu2bdvW227fvn2h48455xxve86cOTbff//9Nv/hD3/wxrmf2wBJ6ty5c1rj1qxZk/Gxw+3I3dYo7v8T4Xp2X2vd/4/C7aVofZZf3Ne7hx56yNu31157pbzfpk2bbL722mttdl8Xi1KnTh1v22251qZNG5vDfxObN2+ezd9++21aj4Xy5fnnn/e23feUBxxwgM3HHnusN+74448v9HhuOynJfx098MADs54nyp8ePXqk3Oe27h0wYEDKcVWrVi3061WqVPG23Trdb7/90p1i7LiyBgAAAAAAAAAAIEacrAEAAAAAAAAAAIgRJ2sAAAAAAAAAAABiVGrWrGnSpIm33b9/f5ufeeYZb5/bU97tC7ps2bIcze73tm7darPby1b6/RoOgGvx4sXettsTd8SIETbPmDHDG3f++efbzDo1yMTFF1+cct8333yT1jH69Olj84477mjzkCFDvHHua6Pr+++/97a7dOli8/Dhw20O98J1+0CHhdd12oZ1w8qP6dOnp9zXunVrm8PrNaTSqVMnb/ukk06yefLkyRnODqVRhQql+98pLV++3Nv++eefbZ41a5bNGzdu9MZVq1bN5gULFuRodihLCgoKUu5zP2cNHDjQ5vAaM+7ac2vXrrV5zz339Made+65NrvvERo2bOiNu/XWW20O1zrKh9q1a3vb7roy99xzj7evb9++Nt922202v/jii944d71E971heD0cd91bd83G8Jp5DzzwgM3u+mBXXnmlUD4UtUZN2HfffWfzRx99lPFjXXbZZd724MGDCx3n1qXEOjXYPvd9oyQddthhNv/zn/+0+cILL/TGuWsqF2XSpEk2Dxs2LJspopwIv67dcMMNKce668v98ssvKce570XHjh2bcpz7d4Ann3yyyHmWJqX7EysAAAAAAAAAAECe42QNAAAAAAAAAABAjEpNG7QlS5Z42zVr1rS5Y8eO3r7jjjvO5qJaoBRXlSpVUu674447bD7nnHO8fX/6059snjJlSvQTQ14ZOnRoWuPcS6yBTKTb6qwo4dYUqaRqN1WvXj1v221n4eawN954w+bbb7/d2zd16lSbly5danPjxo3TmivKjhtvvNHm9u3bpxzn/v4tSrjd3jbh+p04caLNf/7zn22mJVrZ0rx5c5tPPfVUm4tqmei2dcqFkSNH2ty9e/eU4w455BCb3fcBRbWIdFsC7b333tlOEeXEhg0bUu7r2bOnzaNHj07reOH2qK5LL73UZreNtNseTZKmTZuW1mOh7HHb6UnSoEGDbH755Ze9fW5r3a+//jrlMd126m6Lv7Bx48bZ3K9fP5uL+n8A5Yf7meOnn37y9lWvXj3l/dx20++9916kc3Jb9I0aNSrSY6P8cd87FtUqNV3uZyOgKEW1M9u8ebO37X5WK8qHH35oc40aNWwOf553W6C6n+1LO66sAQAAAAAAAAAAiBEnawAAAAAAAAAAAGJUatqgHXzwwd52uPWZK5etz1zhFhODBw+22b3Eevny5d44Wp+hKOHL+tyWf67WrVt72/vuu6/NCxcujH5iKJfcy/oPOOAAm//xj39441K1Unv//fe9bbcVRbNmzVI+7oQJE2zu3LlzynFHHXWUzW7bM8lvRXXNNdekPAbKnkaNGnnb4XpMJVV7s4oVK3rbBx54oM29evWy+corr0xzhihL/vOf/9h83XXXpRw3b968Yj9WixYtbHZb9u25554px7mPO2vWLG/csmXLCn2cyy67zNt+4IEHbH7hhRcymDHwm0WLFqXcfumll2wO/35369RtixJunea+Rrdp08bmcBs0lB9t27a1+eijj/b2ue89x4wZY7Pb6lH6ffu0bcKtUJ5//nmb3c/54c9cbiurvn37ppw78kuHDh1sLqrt2cyZM73tN998s1iP++mnn6bct8MOv/257pJLLvH2Pfjgg8V6XJRv4WUoXKk+T4W5r72nnHJKseeE/NW7d29v2/39HP77+a677mrzBRdcYHO4xn788cdCc7h+d999d5vd1v6l/e9HXFkDAAAAAAAAAAAQI07WAAAAAAAAAAAAxIiTNQAAAAAAAAAAADEqNWvW3H333d72v//9b5tbtmzp7bv66qttvvfee3M2pypVqnjb119/vc3uegunn356zuaA/PPxxx9721u3bk3rfqxTg1xw+8676xy4vT0lv6e428u7bt263riVK1favHnzZpvvuOMOb9xdd91lc6tWrWzu3r27N27SpEk2n3POOSm+i9/3L0fZVqNGDW976dKlNjdo0CDl/Q466KC0ju/2Bx84cKDNrFmT/9z138Jmz55d7ON/+OGHNrs9k3/99VdvXOXKlYv1OMcdd1zKfe7aIkAuFLXGgru2yMMPP+ztc9dfmD9/vs3vvPNOhLNDaRZeq9NdizbcP97tLR9+DXXtvPPONof/bpDqsdw1Fp966ilvnPs+w+2Dj/zmrk/0ySefpBxXVC1mY/z48WmNK6l1m1E+3H///TaH1wvr0qVLWsdw1xYBwmrXrm3zLrvsknJcp06dvO0VK1bYHF57ztW8eXObV69ebfMzzzzjjatfv77NX331VREzLl24sgYAAAAAAAAAACBGnKwBAAAAAAAAAACIUalpgzZkyBBve9y4cTaHL3169tlnczaPFi1a2Ny/f39vn9vOYsOGDTmbA/Lbtddem9Y4t9UeEJVKlSp52zNnzix03KBBg7xtt/VZvXr1bHbblEnSF198YfPll19u89tvv51yTq+99lqhOezpp59OuQ/5rV27djb36NHD5ilTpnjjimrNk8oJJ5yQ1riJEyfa/Oc//9nbN3ny5IwfF/G44IILUu6bOnWqzV27drX5hhtuSPv4r7zyis1ua5PPPvss7WNk47nnnrPZfV1320xK0gcffJDTeaB8uvnmm20+/PDDbXbbnoU1bdrUZvf/G0n/z959h0lRZX0c/12ySFaUJMFFRTGw6COIoLCKCuYcUMKu4XUVlVWMqJhQTKuCIroSjGtYEEVdjIDoqiiiawAzAoIigmQUqfePbu7eKqeGrp7qru6e7+d5+vHU1K3qw/Sxurpr6lz17t07xuxQSFauXOlb7tWrl43dtmdBbo0FtW7d2sbu53W3rZUkffvttzauVauWjb/++mvfOLe1Cu/vlUem54NxcL/7qlLF//fTv/32m43PP/98G7ufsYCKcltFBduezZo1y8ZuS8DgObTbzhQIWr58uY2DbdDcz0Xud0tBX375pY2D34+69bfffvvZ2G3fL/mPqcEWaYWMO2sAAAAAAAAAAAASxMUaAAAAAAAAAACABBVMG7QtttjCt1yjRg0b//DDD751ixYtylkePXr0sLF7W7bkb812zz335CwHlB63vd5BBx2U0TbbbrttrtJBJeMeTw855JDQcW6rhxEjRoSOa9WqlY3d20ol6dFHH7XxF198ESlPYJPy2pndcMMNsT7XlltuaeM1a9b41tWuXdvGa9eutfG6detizQGFwW27e++999p4xowZGe/jyCOPjDWnMG6bNsnfIthtA7Tjjjv6xtEGDbnwl7/8xcZNmjQJ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Koo2aMHb7cIE20adc845NnZbTNx1112+ce6tfYceeqiNn3nmGd84WqUgDrfeeqtveciQITaeM2eOjffff3/fuAcffDC3iaFSqFu3rm95/vz5ZY779NNPfcs777xzmeOmTp3qW+7evbuNaYmGbAVbRWTb7iyMe3v/8OHDbRzW8geIm9v2tHnz5jaeMmWKb9w111xj45deesnGtKFCFMH2UldffXWZ49y6lKQ6derY+KGHHoo/MVQ62267rW/ZbTtujPGtW7BggY2bNGmS28SAmJX32d09r3Xbokr+c4IXXnjBxr169YoxO1RG7vQPruB0DzfddJONL730UhsHP4+5378Gj+1A3ILtzdzvmh599NHQ7d59910bB7+LLWTcWQMAAAAAAAAAAJAgLtYAAAAAAAAAAAAkqCjaoK1evdq3XL9+fRu7t+K5t1FL0j//+U8b77nnnjZu3bq1b5x7y3/t2rVtfOKJJ/rGtWzZ0sbdunXLJHXgdwYOHOhb/vnnn23crl27fKeDSubmm2/2LX/00Uc2btCggY2PPvro0H247frK07VrVxvTEg2b47YrzdS0adNC1+2www42btasWei4c88918ZXXXWVb92KFSsi5wREtXDhwozGvfnmmzZu1aqVb11YS0tUXm7rsyVLlmS0zZo1a3zLI0eOtDFt0JALS5cutXGwxc7DDz9s46pVq+YtJyBbl112mY1POeUU37psWvq657Jbb721b92PP/4YeX+o3NxzAfe88bvvvvON69u3r43dOgvW4NChQ2POEPBzW6OXdwx11wVbqo4fPz7+xPKAO2sAAAAAAAAAAAASxMUaAAAAAAAAAACABHGxBgAAAAAAAAAAIEEFO2fN3nvvHbourB9dsIfdokWLbOz2Yfzggw9849weuG5PvGCvu3322cfGr7/+uo2ZvwZRnHTSSb7lF154wcZVqvzv+mm/fv184x588MHcJoaSFZyny7Xrrrva+IsvvrDxr7/+6htXvXp1G7vz2UycONE3burUqTbu3r27jd35ayTmsIHUvn173/KIESNCx7rvx8OGDQsdd8stt9j44IMPtvGYMWN847bYYgsbz54928avvvqqb9xee+0V+lxALvTq1cu37J7LunPcvfTSS75xzHmH4Jwemc5TM2XKFBv36NHDt455ahA3d+5ZSerdu3fenvvWW2+18YUXXhg67q233rKx+7lt3rx5uUkMJePaa6/NaFzPnj1tPHbsWN+6Fi1a2HjSpEk2dufDkcqvYaAsbq2tX7/exsHPP3//+99tfPnll9v4uOOO842rVatW3CkC+vDDD23sfrfUuHFj37gFCxbY+KCDDrJx8LpAly5dbOweUwsdd9YAAAAAAAAAAAAkiIs1AAAAAAAAAAAACSrYNmg1atSwsduaLMi9xWnw4MG+ddnclhfWEk3yt2Fxb6UKtm4ZOHBg5OdF5bFu3Trfstv6zHX99dfnIx1UApdeeqmN+/TpEzqubdu2Nt64caNvndsibeedd87oed3bVmvWrJnRNlF06NDBxm4rKxSuHXfc0cbPPfdc6Ljg7cvDhw+3sXvMvOKKKzJ6XrftWZBbR+W1DATyYdttt/Utv/zyyzZ2j9+nnXZa3nJCcRg1alTGY99++20bN2jQwMblHSuBOHz22We+5W+//dbGrVq18q1r2bKljZs3b27jhQsXZvRcbtszSRo0aJCNg+e5LrdVm9uuepdddsnoeVG5PPHEEzZ220MHzynd9+1mzZrZ2G17FnT++efb2G3vC4S57777bBw8ph544IFlbnPRRRf5loPtKjf56aeffMsbNmzIJkVAnTp1svGpp57qWxdslb5J8Pv9E0880cZuG7Sgjh072pg2aAAAAAAAAAAAAMgIF2sAAAAAAAAAAAASxMUaAAAAAAAAAACABBXMnDW1a9cOXRfs4+nOHTNt2jQbB3vgupYsWRI5J3f+GsnfQ9+dz2annXbyjatTp46NV61aFfl5Udr69evnWx4zZoyN+/fvb+Nu3br5xr322ms5zQulo127dqHryutH/+WXX9p4/vz5oeOeffZZG48fP963LljfmwT7NrvP5QrObbN+/Xobu3OLSP6+0G3atAnNF4XjjDPOsHF5Pbp/+OEH33Kmc9O4gu/hYVasWGHjBQsWRH4eIE7ff/996LpffvnFxsFj73vvvWfjOXPmxJ8YClLfvn1t/Je//CXj7dz32v322y/WnIDyuHPXBQXnq3PPWd25EzN1zDHHhK5bvXq1jQ8//HDfuldffdXG99xzT+TnRWnbf//9fctunbnfU22zzTah+5g7d66Nn3/+ed+63r17l7nNxx9/HClPVA677rpr6LrgHDXuuaP7/Wjwu1J32Z0npGHDhqHPtd1229m4vO8RgKDjjz/et+x+x3/dddfZ+Ndff/WNe/jhh23sfldQ3nnGlltuaWP3PKAQcWcNAAAAAAAAAABAgrhYAwAAAAAAAAAAkKCCaYO2Zs0a3/JZZ51lY/d20iD31qXnnnsu/sQcbh5uG7QgWp+hPJdddplvOazlSZcuXXzL9evXt/HPP/8cf2IoGcEWOCeeeGJG282aNSvycwXbUrj7aNq0aeh2gwcPtvG3335r46effto3rkePHjZ+6aWXQvfXtm3b0JyQrPbt29s42DY0TMeOHX3LTZo0sfHixYsz2kemrdNef/310HW9evWy8QsvvJDR/oCKOOGEE3zL7nu/2xayWjX/KfyHH35o4xo1auQoOxQC9/1u7NixWe3DbSt6xBFH2Pjxxx/3jdu4cWOZ25977rm+5bvvvtvG7vF60aJFvnHNmze38cKFCyNkjFIRbFv+yCOP2Pjkk0/2rfv3v/9t4+7du9u4vJalgwYNsnHLli1969w2a277P/c4G8zRPe4CkvTMM8/4lt3vo9wWO0uXLs1of4899phv2a3NefPmZZMiKpGPPvqo3GWX267cbUft1q3kPybutttuoftz140YMWLzyQJpbov8rbfe2rfOPQa6bZ7Lc8kll9h4woQJvnXuFAGF3vrMxZ01AAAAAAAAAAAACeJiDQAAAAAAAAAAQIIKpg1a0B133GHjQw891LeuXr16Nh4/fryNjzvuON+4p556KtacbrzxRhu7t1Fn2tYFkKQff/zRtzx79mwbu20pgmrVqmVj2qAhKNjCwVW3bt3Qdd98842Ng+0nwgRb+bn23HNPG7vHyRkzZvjGNW7cOKPnKu9WVbctFa3PCtfHH39sY7eVXbCtndsCr3r16r518+fPz+i5+vTpY+Odd945o20OO+wwGwdbnLrraImGXHHPa4M6d+5sY7dNQLAN0MqVK208fPhwG7ttAVAa3nnnnYzGnXfeeTa+6667QsedccYZZcaSdNNNN9n4lFNOsfG7777rG7dhw4Yy9z169Gjf8g477GBjt83FwQcf7Bs3derU0HxRWg444AAbN2vWzLfuzjvvtHF5rc9c3bp1C13ntqX69NNPbezWZXA50+dFaXNbNgc/h7t1675n77XXXr5x7nGzYcOGoc9Vp04dG7vfMx199NG+caNGjdpc2qiEGjVqZON169b51v3www82dt/fgyZOnGjjVq1a2dj9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bYkWbFN21FFH2XjSpEk2HjNmjG+cuw/XDjvs4Ftu166djb/44osIGVeM53kmb09WAgqlTrPhtmDp37+/b926devK3GaLLbbIZUpRvOd53l5JJ1EsCqVOq1evbmO3JUmwDdpZZ51lY/eWzrZt2/rGXXrppWU+z6233lqRNONEnUZQKHWaKfd4WF6LnWHDhpX584svvti3/N///tfGr7/+uo3PO++8bFPMFHUaUdy16r4f9+3b17fu8ssvt3GXLl186wq99VncOEeNptiOqWGaNGniW164cGFG29WrV8/GwfOMHOOYGkEh1umNN95o42AbtDDG+A9PYd97VKtWMJ3hqdMICrFOs1G3bl3fcrCF1CafffaZb3mXXXbJWU6bQZ1GVOi1etppp/mW77rrLhu77SR79OjhG+d+L+sKtkJ3W1DmswUq56jRFHqd5pN7vA1+b3DSSSfZONga0BXh3KLMYyp31gAAAAAAAAAAACSIizUAAAAAAAAAAAAJ4mINAAAAAAAAAABAgopyzhqX2ycx2Btxw4YNZW5TtWpV37Lbz7a830dS/WzptRhNIdZpNubPn+9bbtasmY2//vrr0O2Cc4jkEf1rIyiUOnWPhzfccION//rXv/rGff7552Vuv8cee/iWa9eubeNffvkljhTjRp1GUCh1GubQQw/1LX/44Ydljjv77LN9y8G5acK0aNHCxosXL46YXYVQpxHls1YvueQSGw8fPoQaB/UAACAASURBVDxfT1uQOEeNptCPqZkK9q1/+eWXyxy3Zs0a33JwboY84pgaQaHXaefOnX3LL774YpnjZs6c6Vs+4IADcpZTTKjTCAq9TrN1//3323jAgAGh49q3b2/juXPn5jSnAOo0okKv1e7du/uWX3311TLHTZ061bdcpcr//va/W7duNg7Ou7T11ltXLMEscY4aTaHXaVLc+RYl6YknnrDxCSec4Fu3YsWKbJ6COWsAAAAAAAAAAAAKDRdrAAAAAAAAAAAAEpRMX68YPfnkk6HrHnvssYz24bY+c1uiBdulAbnWoUMHGzdp0sS3buPGjTZu06aNjctriQZszplnnmnjefPm2dhtZyZJ7dq1s3HNmjVt3Lx5c9+4hg0b2vj777+PLU+gLOeee65vuWfPnjYeNWqUjYNt0MKcc8458SSGklbZW5+hctp2221tHNb2LGi77bbLVTqo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L1q0yMYvvPCCjXv16pW3nFC5DRgwwMbuvDR/+tOffOMOO+ywfKUEZOyf//ynb/mkk05KKJP84M4aAAAAAAAAAACABHGxBgAAAAAAAAAAIEHG87zMBxuT+eCIfvvtN9+ym1fwluhzzjnHxmeffXboPt3b+dyWVOX9m//zn/+EruvWrVvoulzyPM8k8sRFKpd1Wh631Z4k1apVy8Zz5swJ3W633XbLWU559p7neXslnUSxyGednnHGGTZ22/JEsd9++5X581y3R+vQoYONZ8+eHccuqdMI8lmn7nlAlHOTTDRq1Mi3/Ouvv9p47dq1sT5XTKjTiJJ67y+P2/onaP78+WX+vFWrVr5l99xi+fLl8SQWI85Ro8lnnbot+U4++WTfuiFDhtj4oYceyldKSeKYGkEcdbrjjjva2D1X/O6773zjBg0aZOPXXnutok9bLveYXK1aeDf4YMvqPKJOIyiU9/2Knr82adLEt/zjjz9WOKcco04jSqpWW7Zs6Vs+66yzbHzppZeGbufW4NChQ208atSo+JLLA85RoymUY+qJJ55o40cffTR03CWXXGLj8ePH23jJkiW5SSx3yjymcmcNAAAAAAAAAABAgrhYAwAAAAAAAAAAkKDw+3/zYM8997RxebeM1qhRw7d88cUX2/iee+6x8fvvv+8b98EHH5S5v2DLNdc+++xjY2P8d82NGDHCxpdddpmNV61aFbo/VB4DBw70LbutTNx2E0CuNW3a1Lc8efLk0LGffvqpjXfeeefQcdOnTy/z52Ht0aTsWqS5bc8kadasWTYOtg064IADbPzFF19Efi4kq7z34kwF26k0a9aszHGvvvpq6D722otODsiNhQsXhq576623bNymTRsbv/TSS6HbtGvXLp7EUJKuuuoq3/KaNWts3KJFC9+6MWPG2LiStEFDnrmfi7baaisb33LLLb5x7ntwHG3Qbr31VhtfeOGFoePcY3D9+vV963bZZZcK54HK45FHHrHxKaecEnl793uloPJqGNichg0b+pbDWp8FW+/Vrl3bxm5rfyAf3M/z5V0ncM8zPv/8cxtPmjQpN4nlGXfWAAAAAAAAAAAAJIiLNQAAAAAAAAAAAAniYg0AAAAAAAAAAECCEp2zxrVixQrfcr169Wxct25d37qOHTva+LrrrrPxYYcdltFzVa1a1bfs9s131wX76e+0004Z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N91k8yGHHOLs0z1x//Of/xR1SoHz8/e4j6tHHr0Ww4m61+I999xj85133unsK1OmTErP8f7779t8/vnnRzOx7EP/2hCirtO77rrLZr3+QSbMnTvX5s6dOzv72rRpY/OKFSts1r3zRdy1aa666qqop5gMdRpCtqxZs2bNGpv/8Ic/2HzQQQcFPkb3vx01apSzr0WLFjZPnz495XkUI+o0pOLss5yOtWvXOttVqlQpdJx/vQW9rdcEyxaco4YTdZ3qtWhOO+00Z58+f33++eejfNnfOfzww21evXq1zf717/T5cLK1RTKAY2oIqdbpsmXLbK5Zs6azb9GiRTbXq1cvopkVePjhh53t7t2727xkyRKbu3bt6ox76qmnbJ46darNPXv2jHR+RUCdhpCNa9bo74+OOOKIwHH6s5ReW1REZN26delMsThRpyFlslb9x94bbrjB5t69ezv7fvjhB5srV65sc48ePZxxw4YNi3KKseEcNZziPKZ27NjRZv/3REHatm3rbPvXRM5hrFkDAAAAAAAAAACQbbhYAwAAAAAAAAAAEKNSxf2Czz33nM269Y2/tcMdd9xhs/+2ft1KQu9bv359kef397//3eZevXo5+9544w2b/bdgIX8NHDjQ5mSt8W655RZnX/ny5W3WbSDOPfdcZ9x7770XxTSxn0t2/Pvvf/9r82WXXRY47oQTTrBZt1bxa9Sokc2zZs1y9pUq9dvbir692i/V212xf5o9e7azreu2efPmNut2en6DBw+2uVWrVs6+iy66qNCcqu3btzvbHMexL/42QLqNT/v27W3esWOHM07X2ldffWWzPicVCT5m165d29kuUeK3f6c1duzYfcwa2U63fLrkkkucff/85z9tfuKJJ5x9r7zyis3XX3996NetVq2as92nTx+bjz32WJvPOeccZ9zixYtt1p/nWrZsGXoOiN+FF15o85w5c5x9J598ss36s0+m3y9166mff/7Z2aePtQsXLrTZ//numWeesfmXX36JeorIQfpzy1/+8pfAcbo99MyZMwPH6c9SM2bMcPbpdn0jRowINU/sf3R7aBG39ZluIy0icvHFF9t8991326zfw0VEdu3aZfOECRNsXrlyZdEmCyRUr149cN/bb79t8wUXXGCz/7PPAw88YLP+Hn/Lli1RTDF23FkDAAAAAAAAAAAQIy7WAAAAAAAAAAAAxIiLNQAAAAAAAAAAADEynuelPtiY1AcnnH766c627t156KGHhn26vfOwuWrVqjZHsWbNgQceaPM999zj7Lvrrrtsfumll2x+8sknnXHz5s0r8jw0z/PMvkdhr3TqNApNmzZ1tseMGWOz7sn4448/OuOGDx9u82OPPWazv89yDljgeV79uCeRK6Ko03Llytn8008/BY7TvbgbN27s7Fu+fLnNuo9tlSpVnHFnnnmmzXXq1LHZf4wPek+ZOHGis617Om/atClw7hlAnYYQRZ3u3r3b5lTPOQYNGuRs9+3b12bdc/7GG290xvnrO4g+jwhzHrTXtm3bnO1rrrnGZn8/3TRRpyHF9d4fhUmTJtmsa1NEpE2bNjb717NJhf/5dL0//fTTKT3HDTfcELiPc9RwoqjTihUr2pzqZ59ff/3V2a5f/7fDy+eff57Sc+ha0muLiog8+OCDKT2Hpt8b2rVr5+zT/01EhGNqCKnWqf4M061bt8Bxf/3rXwP3JVt7Lshtt90WuF2zZs3A5+7SpYvNuqe9/zipn2P16tWh51cE1GkIxfm+r78HGjBgQOC4Zs2a2azPV0Xc9ZT0el6HHHKIM06vF1KmTJnwk8086jSkqGv1lFNOCdz36aef2vzCCy84+66++mqbX331VZuTrcc9evRom/V6iyIiS5cu3fdkY8Q5ajjFeUzV54D+81C9ptfGjRsDn0O/d7/++us2++t+8uTJac+zmBR6TOXOGgAAAAAAAAAAgBhxsQYAAAAAAAAAACBGpTL9AgsWLHC2zzvvvMB9QXr27Ols69vtomh9FmTgwIHO9jHHHGPzlVdeafMBBxzgjIu6DRpyw/bt253tt956y2bdIqdChQrOOH2b38iRI23OwTZoKGabN2+2edGiRTbrNmUibm3u2bMn8PmS3SJauXJlm3U9J2sh9cADDwTuK+bWZ4hRiRK//bsQfcuzn259ptue+ZUsWdJmffxMxt/i5PHHH7f5lltuSek5tIMOOsjZ7tq1q80RtUFDnuvQoYPNDRs2tPm0005zxu3cudPm1157LdI5XHfddc52UHvAZG3QkL1mzJhhc8uWLdN6jptvvtlm3arXT58XPPPMM4HjSpX67aOnPpb36dPHGTdlyhSbk523IF76/dN/7GrQoIHNuiWJbu2YLn1eIeK2LduwYYPN/vYpupXkihUrAp9//PjxNvfr18/m6dOnh54rclOPHj2c7f79+9us20yJiLRo0cJmXX/vvfeeM+6KK66wOdkxWR8njzvuuMBxX375pc0cJ/cv+jvQDz74wNmnj3P+71G1VFvsVatWzeZsb3uG7OX/DmDWrFk2X3jhhc4+/dlHH+f0e72Iu4SJPrfQbSZFRF5++WWbu3fvHmLW0SlbtqyzfeSRR9q8ePHiQh/DnTUAAAAAAAAAAAAx4mINAAAAAAAAAABAjDLeBi2ZNWvW2Kxvr/O7+OKLne1LLrkkY3PStw3Wq1fP2advcdW3Tutbs7D/mjNnTuD2tddeG/i4Zs2a2fzqq6/avGzZMmfc4MGDbV6yZEna80R++vDDD20++eSTnX21atWy+Z133nH26fpL1hJC0+0ndCs2Ebdu77jjDpvTbcGC/OJvR6b525oE0bcy+1vnnHDCCSk9x+jRo23WLU6aN2/ujNPtfA4++ODA5/v6669Tel1gL90qVbfVa9y4sTPuxRdftLljx44ZnZNu8TN27NiMvhYyT7fd9bdf2LJlS0rPUb9+/UL//F//+pezrduo6rYU/rZRF1xwQaHPp89xRWjpk4v87c1Wr15ts26rqFuMibhtTfRjwpg0aZLNl156qc1XXXWVM+7111+3Wbdd8X+G0/+96PNX2qDtPx555BFnW7f1a9u2rbOvUqVKNus2aH76fV+3+7333nudcbrFvm6Pc+uttzrjvvvuO5v9Lf+Q3/T3qP7WZPqY6m+Dduedd9p844032uxvpaZbNLVq1cpmf8t0fWzP5He0yH2ff/65s92kSRObzzrrLGefbiGpP9v7a0yfT+jvGHT7fhG3Zav+rkp/p5Au/7IsJ554os36Owb/OZJudxmEO2sAAAAAAAAAAABixMUaAAAAAAAAAACAGHGxBgAAAAAAAAAAIEZG9xnc52BjUh+cgjPOOMNmvVaHiMgRRxyhX9fZN23aNJv969lkUvfu3W1++OGHbZ47d64z7uyzz470dT3PC27yj9+Juk6joHvZzpgxw9lXt27dQh/jX79B9+/WvWyzyALP8wpvbo7fibpOjzrqKJv/7//+z9mn10Pwe+2112y+4oorAsfdddddNg8cONDmN954wxmn+9/qHp7+tb30WjkrV64MfN0MoE5DiKJOu3btavPw4cMDxw0aNMhm3cs7mSuvvNLZfu655wod5z+e1qlTx+ZFixYFPn/nzp1tHjp0qM3lypVzxn3//fc2V69ePcmMU0adhpSN7/2p+vnnn23+5z//6ezT557ZiHPUcKKo04oVK9rs75UdZOHChc62/hzzyiuv2Ny0aVNn3NNPP21z+fLlbfb3Fw86jvbv39/Z9q8zttdHH33kbJ9//vk2b9u2rdDHhMQxNYQo6lSvI6PXfUn2ud5/vNu+fbvNq1atCnwtvc5sr169bE62zpfuF+9fs/Hwww+3Wa/NqNfDERGZPXt24POniToNoTjf92+66SabH3vsscBxqaxD4Of/PmvChAmFjvN/bzdu3Dibr776apuLYc0v6jSkTNaq/7sl/T7+7LPPOvv0e/CmTZts1p/LRX7/+X4v//Fb1+T8+fNt1mstiYh8++23NuvzlhEjRhT6OlHhHDWcTNap/zsA/f3A+++/7+xr3bq1zbpOy5Qp44zT78F6jUW9ppOIu7as/q4+zLUQTf938Oc//9nZ98ADD9is1yH117peR0cCjqncWQMAAAAAAAAAABAjLtYAAAAAAAAAAADEKNY2aJr/dvpZs2bp13X26TlffvnlNs+bN88Zl+x26aJavny5zfpWaRGRf/zjHzbfdtttRX4tbt8LJ9tboeh2VSIiF154oc2DBw+22d9mR9/SPHHiRJuvueYaZ9wvv/wSwSzTwi3RIWSyTp966ilnu0uXLoFj9W3JtWrVChx366232jxs2DCb/beZ1qhRw2Z9O/Spp57qjNOtUfTtort37w6cQ0So0xCiqNOTTjrJ5unTp9vsbxemW4mddtppzr5169al9Fr6dmh9W7L/POKUU06xOVkbNO2vf/2rzf62AkHPHeb5fajTkLL9vT+ZJ5980mbdzkdEpFGjRsU9nVA4Rw0nijotWbKkzboNTtu2bdN6Pn3c1C0bRNxzSn2++eabb6b03P5Wv/o9oGrVqoGP03+XoJZAIXFMDSGKOq1du7bNunXfSy+95IyrWbOmzfqcVMRt1avb8ab6urrdn4jbjq1nz542++u0U6dOhT63foyIyKOPPprSnEKgTkMozvd9fWzULf5ERMqWLWtzw4YNbf7kk0+K/Lr6e69k7c10C8HHH3+8yK+7D9RpSJms1VGjRjnbf/vb3wLH6paPuvXUeeed54wLaumc7HvZVOnneOaZZ5x9119/fejnS4Zz1HAyWacNGjRwtvX3mXrJCBGRmTNn2tyiRYvA59TfXS1YsMBm3V5axF1+Ze3atTan2zJSt1dP9t3VO++8Y3OHDh2cfbq9m9AGDQAAAAAAAAAAIPtwsQYAAAAAAAAAACBGWdMG7eCDD3a2R44caXOrVq2cfYceeqjNur3I+eef74zbsGFDlFN06Ntf9S3V/tetUqVKkV+L2/fCyeVWKK1bt7b5jTfecPYF3abnb/+n26nMnTvX5u+++84Zt3379rTnGYBbokPIZJ0ef/zxzvaHH35os7+9nqZvedYtqfwmT55sc5MmTZx9uq3f0qVLC32MiEj9+r+VSr9+/WzWrQBFRHbt2hU4jzRRpyFE3Qrl7bfftvmII44IfMzRRx/tbK9cuTKl18pkGzTdxmXGjBnOPt3mTx+DRdwWgiFQpyHl8nu/bqXjb21aoUKFYp5NOJyjhhN1ner2J8lan/iNHj260MfpY6iIyHXXXWfz119/nc4UHcOHD7e5W7dugeP0+evZZ59d5NcVjqmhZPJ4qs8JRESuuuoqm3v06OHsK126tM133323zbp9j4jIDz/8YPNXX31ls/9z+Pjx423W7apS/T7E3wI1zH9zKaJOQ4jrfV+3khJxPz/dfvvtNj/xxBNFfq0HH3zQZn9L6WbNmhX6GP+x+oILLrBZt/IvAuo0pEzW6sknn+xs65ZmgwYNcvYddNBBNhe1hZn/OcaMGWOz/1zi3nvvtbl8+fI263ZSIiKdO3e22f/dQTo4Rw2nOI+pHTt2tPnpp5929ulrA/rzt691mOODDz6w2d9yTbc61S3X9H8PIu7n++bNm9t8zDHHOOP+/e9/26zPK0TcY7bel2zuQhs0AAAAAAAAAACA7MPFGgAAAAAAAAAAgBhxsQYAAAAAAAAAACBGpeKewF5bt251tnX/bv+aNbrfW7Vq1WzWayCI/L6nfJSef/55m/1r1mi1atVytnUfXcBvwoQJNv/pT39y9t155502d+nSxWbdc9m/rfuADhs2zBnXs2fPok0WWUv3SxZJvk6Npo9Xydasuf/++21u0aKFs0/3ydW9Q2+++WZn3HvvvWezXrPm5ZdfdsZxzMx9es2DVNepSXWNmnSVKVMm9GN+/PFHm2fOnOns033EI1pfAfuRVatW2exfw1G/p/vXqMP+qVOnTjYnWzNDr5flX0tL+/nnn23W78ciIlu2bEljhsH0Gg7689NRRx0V+JiyZctmdE4oXno9QxF3zdkDDzww8HG6D7x/3QS9hoj+jK7XSRBx17JbvXq1zf51QfV58yGHHGLz1Vdf7YzLwJo1yFK6xvQaNX4PPfSQzZ999pmzT38uSpVeq0mv4STirnGnj/H+7xCQ3/xrb7Zr187mZO/9ep1Z//ml/r5Vr3Pk/4zTpk0bm/V6oN27d3fG6TU+LrroIpsfe+yxwPn51xPZtm1b4FjkHl1X/s8+2sCBA23W34eKuDWh15T3r1mjj5V33HFHSvNLdi1BrxPlX4cvStxZAwAAAAAAAAAAECMu1gAAAAAAAAAAAMQoa9qg+S1YsMBm3VZHRKRXr1426xZp27dvz+icatSoYXP//v1t/vLLL51xxx57rM1du3Z19vXo0SNDs0O++fbbb53tkSNH2qzboPnp1me//vqrzTfddJMzjjZo+ct/i6i+tbl9+/bOPt2ias2aNYHPqW9PffPNNwPHnXHGGYX+uf+WU31rc+/evW1u3bq1M+7hhx8OfC3khrFjx9p83HHH2exvJbZ27drQz923b19nW7c40W1S/K1QPvnkk9CvpVuwJOO/lbtq1ao2r1u3LvTrIj/Vq1fP5r///e82+9vq0PoMfnPnzk1pnG7P6G+Hqluc6M9VmZZq67NGjRrZrNsAiYj06dMn8nkhPvp3femllzr7dMsd/Rna37asVKnfvtLYtWtXSq+rv0Pwt5TW7foAEZFly5bZnKwN2nfffWdzOi13k9F1LvL778iCTJ8+3ebhw4c7+959912blyxZUoTZIVv425kGueeee2zesWNH4LiSJUva7G+Dpj9rjR8/3uadO3c643TbSf3fyOWXX+6M00sC6PZXIiL33Xdf4ByRe/Rncf93m6NHj7a5Zs2aNvtb4R122GE2P/DAAzZ//fXXzrhUW5+lyt96MFO4swYAAAAAAAAAACBGXKwBAAAAAAAAAACIkfE8L/XBxqQ+OINq165t8+LFiwPHvf/++zZPmjTJ5ldeecUZl2rrFd2yYurUqTbrFiciIvr/U//tqunwPM/sexT2ypY6jZquv7ffftvmP/7xj8443QbN3yZA++abbwL31apVK50pLvA8r346D9wf5XKd6lZn/nYs+lb7Tp062exvMTF58mSbp02bZnO7du2ccbqVX0So0xCyvU79bXR0Owd9a36TJk2cccuXLw/9WroNWrLbqf0tJ3ULyxCo05CyvVb9TjnlFJs//fRTm6dMmeKM87cFyjaco4YTRZ3qlhALFy60ecOGDc443d5MtxaJk/7M9K9//cvm448/3hm3detWm3UbahGRjRs3pvPSHFNDyJbjaYUKFWzWLXj9rXhSFfS53H+O+sEHHxQ6TrcDyhDqNITirNNq1arZ7P/s4z9GBY3r0KGDzVG0xdXtLQ8//HCb/W33O3fubPOoUaOcfY899pjNIdqgUachZcsxNWpB3zVdcsklzrY+tz3ggANs9rfEPvnkk23Wba1ERIYNGxZ6fpyjhpMtdTpgwACb9dINM2bMcMbdeuutNif7brMY3ruLqtBjKnfWAAAAAAAAAAAAxIiLNQAAAAAAAAAAADHiYg0AAAAAAAAAAECMcnLNGk2vRdOyZUtnn+5Xr/+e33//vTOuevXqKb3W448/bnO3bt0Cx+nXjaI/Hr0Ww8nGOi1OY8aMsblp06Y2+9dW0mvb+KVZt/SvDSGX61T3mm3RooWzb/z48TbfcsstNvvXCtN9nPUaSbrnsojId999V7TJ/h51GkKu1anudawtWrSoyM+d6po1/rUh/OswpYg6DSnXalX77LPPbF6xYoWzjzVr8kvUdarXM/TXzo8//hjlS0Xu3HPPtfmdd94JHKePvSIiffv2TeflOKaGkI3HU70+R+PGjZ19Rx99tM3J1jXQ3xvo7waSHWdnz55t8/nnn5/aZNNHnYYQV53qz9ci7jnheeedF/g4vZ5ysnFF5V8DLNk5sF7D8X/+539snjhxYrKXoE5DysZjahT69Oljc//+/QPH6drXx97169c749q3b2+zPvaKuOcMqeIcNZxsrNPdu3fbnOq1i59++snZrly5cqRzygDWrAEAAAAAAAAAAMg2XKwBAAAAAAAAAACIUam4J1BU+la5U0891dk3dOhQm3WbgMMOO8wZ980339isb49u3bq1M87fRipImNZyQNQ6d+5ss677ChUqOONmzpxps25JBezLzp07bX7rrbcCxw0ePNhm/+2oW7ZsKfQx1157rbM9aNCgdKaI/VRR250ddNBBznalSpVs1i1YkvGfOwBApixcuDDuKaRt8eLFNi9btszZd8wxx9hcqlTOf1xFBDZv3mzzlClTnH36/fmrr76yuW7dus443VIv2ef1rVu32qy/TwBEft+2UW9v2rTJ5oMPPtgZV758+cxOLOGLL75wtnUr6kMPPdTZp9tZv/HGGzZz3EUqdPt93YpVLx8h4rauTHbs1fvq16fTHkTuv/9+m/1LkejP6bqlXr58FufOGgAAAAAAAAAAgBhxsQYAAAAAAAAAACBGOX9/444dO2yeN2+es69Ro0Y2X3TRRTb725yMGzfO5ptuuslmY4wzLuiWvfnz5zvbM2bM2Ne0gWKRrD1Gs2bNbPbfLg2k6tdff3W2hwwZYnOvXr1sHjVqlDOuZMmShT6fv00lUJzOO+88Z3vixImhn8Pf8g+547LLLrO5TZs2aT3HVVddFdV0gLz23Xff2ew/X9Vt0PRnOBGRu+66K7MTQ87RLdKmT59eaBb5fUvovfzv9brd74IFC6KYIvYT7dq1s7lHjx7OPv9noeJy5ZVX2nzSSSc5+3Q7yrfffrvY5oT8sGbNGpuff/55m1euXOmM09877dmzx2b/5/4uXbrYPGDAgMjmidzVv39/m/3t9UqXLm2z/k5q48aNmZ9YMeDOGgAAAAAAAAAAgBhxsQYAAAAAAAAAACBGXKwBAAAAAAAAAACIUc6vWZOqKVOmhH5MqmvWfPjhh8727t27Q78WUNxmzZoV9xSQh+69916b9TG0Z8+eKT3+008/jXxOQKr8/bpnzpxps+63nMw999wT6ZxQfOrUqWPzmWeeaXOJEu6/bapSpYrN/nUQP//8c5v9axpqFStWtLlmzZo2r1ixIsSMgfxwww03ONt6zagTTzyxuKeDPMV6R8g0fR6ZjWvA6HMUEZE777wzppkgn/m/Z0r1e6f//ve/Nj/77LMRzgj5IF/WokkVd9YAAAAAAAAAAADEiIs1AAAAAAAAAAAAMdpv2qAl89prr8U9BQDIC3v27LF5+fLlNq9fv94Zt27dOpvPOeccmzdv3pzB2QHJNWjQwNmuVq2azYsWLbL5mmuuccbp2/Z37NiRmckh4/r3719o9qtbt67NLVu2dPY9+OCDKb2Wbq1799132/zQQw+l9Hggn4waNSpwX8mSJYtxJgAAIA6PPvpo3FMAsgZ31gAAAAAAAAAAAMSIizUAAAAAAAAAAAAx4mINAAAAAAAAAABAjIzumb3PwcakPhiR8TzPxD2HXEKdxmaB53n1455ErqBOY8QAYJkAAAHWSURBVEOdhkCdxoY6DSlbanXMmDEpjdu2bZvN3bp1y9R0Mo5z1HCypU6zjX+9sLlz59oc0Zo1HFNDoE5jQ52GQJ3GhjoNiVqNB+eo4VCnsSn0mMqdNQAAAAAAAAAAADHiYg0AAAAAAAAAAECMSsU9AQAAACAfdO7cOe4pADnno48+craHDBkS00wAAACAeHFnDQAAAAAAAAAAQIy4WAMAAAAAAAAAABAj2qABAAAAALJC7969454CAAAAEAvurAEAAAAAAAAAAIgRF2sAAAAAAAAAAABixMUaAAAAAAAAAACAGHGxBgAAAAAAAAAAIEZcrAEAAAAAAAAAAIgRF2sAAAAAAAAAAABiVCrk+B9EZHkmJoJAR8Y9gRxEncaDWg2HOo0HdRoOdRoP6jQ8arX4UafhUafxoFbDoU7jQZ2GQ53GgzoNj1otftRpeNRpPAqtVeN5XnFPBAAAAAAAAAAAAAm0QQMAAAAAAAAAAIgRF2sAAAAAAAAAAABixMUaAAAAAAAAAACAGHGxBgAAAAAAAAAAIEZcrAEAAAAAAAAAAIgRF2sAAAAAAAAAAABixMUaAAAAAAAAAACAGHGxBgAAAAAAAAAAIEZcrAEAAAAAAAAAAIjR/wfxw+arnLdfjAAAAABJRU5ErkJggg==\n"
          },
          "metadata": {}
        }
      ],
      "source": [
        "# Visualize label 0-9 1 sample MNIST picture in 5 tasks.\n",
        "sample = [Data('data', angle=angle_list[index]) for index in range(args.task_number)]\n",
        "\n",
        "plt.figure(figsize=(30, 10))\n",
        "for task in range(5):\n",
        "  target_list = []\n",
        "  cnt = 0\n",
        "  while (len(target_list) < 10):\n",
        "    img, target = sample[task].dataset[cnt]\n",
        "    cnt += 1\n",
        "    if target in target_list:\n",
        "      continue\n",
        "    else:\n",
        "      target_list.append(target)\n",
        "    plt.subplot(5, 10, (task)*10 + target + 1)\n",
        "    curr_img = np.reshape(img, (28, 28))\n",
        "    plt.matshow(curr_img, cmap=plt.get_cmap('gray'), fignum=False)\n",
        "    ax = plt.gca()\n",
        "    ax.axes.xaxis.set_ticks([])\n",
        "    ax.axes.yaxis.set_ticks([])\n",
        "    plt.title(\"task: \" + str(task+1) + \" \" + \"label: \" + str(target), y=1)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KRh6nIcMC6vy"
      },
      "source": [
        "# Prepare Model"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bLv7CHTHtf53"
      },
      "source": [
        "### Model Architecture\n",
        "To fair comparison, \n",
        "\n",
        "We fix our model architecture to do this homework. \n",
        "\n",
        "The model architecture consists of 4 layers fully-connected network."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "mnpIMLMSs_3k",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "f658c764-1372-483b-ba90-31279d260011"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Model(\n",
            "  (fc1): Linear(in_features=784, out_features=1024, bias=True)\n",
            "  (fc2): Linear(in_features=1024, out_features=512, bias=True)\n",
            "  (fc3): Linear(in_features=512, out_features=256, bias=True)\n",
            "  (fc4): Linear(in_features=256, out_features=10, bias=True)\n",
            "  (relu): ReLU()\n",
            ")\n"
          ]
        }
      ],
      "source": [
        "class Model(nn.Module):\n",
        "  \"\"\"\n",
        "  Model architecture \n",
        "  1*28*28 (input) → 1024 → 512 → 256 → 10\n",
        "  \"\"\"\n",
        "  def __init__(self):\n",
        "    super(Model, self).__init__()\n",
        "    self.fc1 = nn.Linear(1*28*28, 1024)\n",
        "    self.fc2 = nn.Linear(1024, 512)\n",
        "    self.fc3 = nn.Linear(512, 256)\n",
        "    self.fc4 = nn.Linear(256, 10)\n",
        "    self.relu = nn.ReLU()\n",
        "\n",
        "  def forward(self, x):\n",
        "    x = x.view(-1, 1*28*28)\n",
        "    x = self.fc1(x)\n",
        "    x = self.relu(x)\n",
        "    x = self.fc2(x)\n",
        "    x = self.relu(x)\n",
        "    x = self.fc3(x)\n",
        "    x = self.relu(x)\n",
        "    x = self.fc4(x)\n",
        "    return x\n",
        "\n",
        "example = Model()\n",
        "print(example)"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Train and Evaluate"
      ],
      "metadata": {
        "id": "ABoTzmtiumsv"
      }
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oPxS7H4DuQ2W"
      },
      "source": [
        "### Train\n",
        "This is our function of training.\n",
        "\n",
        "It can generally be applied in different regularization-based lifelong learning algorithms in this homework."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "tO6q7ymIuOTR"
      },
      "outputs": [],
      "source": [
        "def train(model, optimizer, dataloader, epochs_per_task, lll_object, lll_lambda, test_dataloaders, evaluate, device, log_step=1):\n",
        "  model.train()\n",
        "  model.zero_grad()\n",
        "  objective = nn.CrossEntropyLoss()\n",
        "  acc_per_epoch = []\n",
        "  loss = 1.0\n",
        "  bar = tqdm.auto.trange(epochs_per_task, leave=False, desc=f\"Epoch 1, Loss: {loss:.7f}\")\n",
        "  for epoch in bar:\n",
        "    for imgs, labels in tqdm.auto.tqdm(dataloader, leave=False):            \n",
        "      imgs, labels = imgs.to(device), labels.to(device)\n",
        "      outputs = model(imgs)\n",
        "      loss = objective(outputs, labels)\n",
        "      total_loss = loss\n",
        "      lll_loss = lll_object.penalty(model)\n",
        "      total_loss += lll_lambda * lll_loss \n",
        "      lll_object.update(model)\n",
        "      optimizer.zero_grad()\n",
        "      total_loss.backward()\n",
        "      optimizer.step()\n",
        "\n",
        "      loss = total_loss.item()\n",
        "      bar.set_description_str(desc=f\"Epoch {epoch+1:2}, Loss: {loss:.7f}\", refresh=True)\n",
        "    acc_average  = []\n",
        "    for test_dataloader in test_dataloaders: \n",
        "      acc_test = evaluate(model, test_dataloader, device)\n",
        "      acc_average.append(acc_test)\n",
        "    average=np.mean(np.array(acc_average))\n",
        "    acc_per_epoch.append(average*100.0)\n",
        "    bar.set_description_str(desc=f\"Epoch {epoch+2:2}, Loss: {loss:.7f}\", refresh=True)\n",
        "                \n",
        "  return model, optimizer, acc_per_epoch"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "c0UF5Ef2us9G"
      },
      "source": [
        "### Evaluate\n",
        "This is our function of evaluation.\n",
        "\n",
        "It can generally be applied in different regularization-based lifelong learning algorithms in this homework.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Z5WPNr38usXt"
      },
      "outputs": [],
      "source": [
        "def evaluate(model, test_dataloader, device):\n",
        "    model.eval()\n",
        "    correct_cnt = 0\n",
        "    total = 0\n",
        "    for imgs, labels in test_dataloader:\n",
        "        imgs, labels = imgs.to(device), labels.to(device)\n",
        "        outputs = model(imgs)\n",
        "        _, pred_label = torch.max(outputs.data, 1)\n",
        "\n",
        "        correct_cnt += (pred_label == labels.data).sum().item()\n",
        "        total += torch.ones_like(labels.data).sum().item()\n",
        "    return correct_cnt / total"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oJSpRj3BD7jF"
      },
      "source": [
        "# Methods\n",
        "- Baseline\n",
        "- EWC\n",
        "- SI\n",
        "- MAS\n",
        "- RWalk\n",
        "- SCP"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yRDSy-keEHcb"
      },
      "source": [
        "### Baseline\n",
        "The baseline class will do nothing in the regularization term."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-sQz7s_-4Olb"
      },
      "outputs": [],
      "source": [
        "# Baseline\n",
        "class baseline(object):\n",
        "  \"\"\"\n",
        "  baseline technique: do nothing in regularization term [initialize and all weight is zero]\n",
        "  \"\"\"\n",
        "  def __init__(self, model, dataloader, device):\n",
        "    self.model = model\n",
        "    self.dataloader = dataloader\n",
        "    self.device = device\n",
        "    # extract all parameters in models\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad} \n",
        "    \n",
        "    # store current parameters\n",
        "    self.p_old = {} \n",
        "\n",
        "    # generate weight matrix\n",
        "    self._precision_matrices = self._calculate_importance()  \n",
        "\n",
        "    for n, p in self.params.items():\n",
        "      # keep the old parameter in self.p_old\n",
        "      self.p_old[n] = p.clone().detach() \n",
        "\n",
        "  def _calculate_importance(self):\n",
        "    precision_matrices = {} \n",
        "    # initialize weight matrix（fill zero）\n",
        "    for n, p in self.params.items(): \n",
        "      precision_matrices[n] = p.clone().detach().fill_(0)\n",
        "\n",
        "    return precision_matrices\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0\n",
        "    for n, p in model.named_parameters():\n",
        "      _loss = self._precision_matrices[n] * (p - self.p_old[n]) ** 2\n",
        "      loss += _loss.sum()\n",
        "    return loss\n",
        "  \n",
        "  def update(self, model):\n",
        "    # do nothing\n",
        "    return"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Jq_AudHg4YoW"
      },
      "outputs": [],
      "source": [
        "# Baseline\n",
        "print(\"RUN BASELINE\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "# initialize lifelong learning object (baseline class) without adding any regularization term.\n",
        "lll_object=baseline(model=model, dataloader=None, device=device)\n",
        "lll_lambda=0.0\n",
        "baseline_acc=[]\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "\n",
        "# iterate training on each task continually.\n",
        "for train_indexes in task_bar:\n",
        "  # Train each task\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, \n",
        "                  lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  \n",
        "  # get model weight to baseline class and do nothing!\n",
        "  lll_object=baseline(model=model, dataloader=train_dataloaders[train_indexes],device=device)\n",
        "  \n",
        "  # new a optimizer\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "  \n",
        "  # Collect average accuracy in each epoch\n",
        "  baseline_acc.extend(acc_list)\n",
        "  \n",
        "  # display the information of the next task.\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch! \n",
        "print(baseline_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DIZ2HiZwELR3"
      },
      "source": [
        "### EWC\n",
        "\n",
        "Elastic Weight Consolidation\n",
        "\n",
        "The ewc class applied EWC algorithm to calculate the regularization term. The central concept is included in Prof.Hung-yi's lectures. Here we will focus on the algorithm of EWC.\n",
        "\n",
        "In this assignment, we want to let our model learn 10 tasks successively. Here we show a simple example that lets the model learn 2 tasks(task A and task B) successively.\n",
        "\n",
        "In the EWC algorithm, the definition of the loss function is shown below:\n",
        " $$\\mathcal{L}_B = \\mathcal{L}(\\theta) + \\sum_{i} \\frac{\\lambda}{2} F_i (\\theta_{i} - \\theta_{A,i}^{*})^2  $$\n",
        "  \n",
        "Assume we have a neural network with more than two parameters.\n",
        "\n",
        "$F_i$ corresponds to the $i^{th}$ guard in Prof. Hung-yi's lecture. Please do not modify this parameter, because it's important to task A.\n",
        "\n",
        "The definition of $F$ is shown below.\n",
        "$$ F = [ \\nabla \\log(p(y_n | x_n, \\theta_{A}^{*})) \\nabla \\log(p(y_n | x_n, \\theta_{A}^{*}))^T ] $$ \n",
        "\n",
        "We only take the diagonal value of the matrix to approximate each parameter's $F_i$.\n",
        "\n",
        "The detail information and derivation are shown in 2.4.1 and 2.4 of [Continual Learning in Neural\n",
        "Networks](https://arxiv.org/pdf/1910.02718.pdf)\n",
        "\n",
        "For You Information: [Elastic Weight Consolidation](https://arxiv.org/pdf/1612.00796.pdf)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9cvqQKL1EVss"
      },
      "outputs": [],
      "source": [
        "# EWC\n",
        "class ewc(object):\n",
        "  \"\"\"\n",
        "  @article{kirkpatrick2017overcoming,\n",
        "      title={Overcoming catastrophic forgetting in neural networks},\n",
        "      author={Kirkpatrick, James and Pascanu, Razvan and Rabinowitz, Neil and Veness, Joel and Desjardins, Guillaume and Rusu, Andrei A and Milan, Kieran and Quan, John and Ramalho, Tiago and Grabska-Barwinska, Agnieszka and others},\n",
        "      journal={Proceedings of the national academy of sciences},\n",
        "      year={2017},\n",
        "      url={https://arxiv.org/abs/1612.00796}\n",
        "  }\n",
        "  \"\"\"\n",
        "  def __init__(self, model, dataloader, device, prev_guards=[None]):\n",
        "    self.model = model\n",
        "    self.dataloader = dataloader\n",
        "    self.device = device\n",
        "    # extract all parameters in models\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad} \n",
        "    \n",
        "    # initialize parameters\n",
        "    self.p_old = {}\n",
        "    # save previous guards\n",
        "    self.previous_guards_list = prev_guards\n",
        "\n",
        "    # generate Fisher (F) matrix for EWC\n",
        "    self._precision_matrices = self._calculate_importance()                   \n",
        "\n",
        "    # keep the old parameter in self.p_old\n",
        "    for n, p in self.params.items():\n",
        "      self.p_old[n] = p.clone().detach()       \n",
        "\n",
        "  def _calculate_importance(self):\n",
        "    precision_matrices = {}\n",
        "    # initialize Fisher (F) matrix（all fill zero）and add previous guards\n",
        "    for n, p in self.params.items(): \n",
        "      precision_matrices[n] = p.clone().detach().fill_(0)                 \n",
        "      for i in range(len(self.previous_guards_list)):\n",
        "        if self.previous_guards_list[i]:\n",
        "          precision_matrices[n] += self.previous_guards_list[i][n]\n",
        "\n",
        "    self.model.eval()\n",
        "    if self.dataloader is not None:\n",
        "      number_data = len(self.dataloader)\n",
        "      for data in self.dataloader:\n",
        "        self.model.zero_grad()\n",
        "        # get image data\n",
        "        input = data[0].to(self.device)\n",
        "          \n",
        "        # image data forward model\n",
        "        output = self.model(input)\n",
        "          \n",
        "        # Simply use groud truth label of dataset.  \n",
        "        label = data[1].to(self.device)\n",
        "          \n",
        "        # generate Fisher(F) matrix for EWC     \n",
        "        loss = F.nll_loss(F.log_softmax(output, dim=1), label)\n",
        "        loss.backward()   \n",
        "\n",
        "        for n, p in self.model.named_parameters():\n",
        "          # get the gradient of each parameter and square it, then average it in all validation set.                          \n",
        "          precision_matrices[n].data += p.grad.data ** 2 / number_data   \n",
        "                                                                \n",
        "      precision_matrices = {n: p for n, p in precision_matrices.items()}\n",
        "    return precision_matrices\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0\n",
        "    for n, p in model.named_parameters():\n",
        "      # generate the final regularization term by the ewc weight (self._precision_matrices[n]) and the square of weight difference ((p - self.p_old[n]) ** 2).  \n",
        "      _loss = self._precision_matrices[n] * (p - self.p_old[n]) ** 2\n",
        "      loss += _loss.sum()\n",
        "    return loss\n",
        "  \n",
        "  def update(self, model):\n",
        "    # do nothing\n",
        "    return "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "8VJ9QUsNIyEG"
      },
      "outputs": [],
      "source": [
        "# EWC\n",
        "print(\"RUN EWC\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "# initialize optimizer\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "# initialize lifelong learning object for EWC\n",
        "lll_object=ewc(model=model, dataloader=None, device=device)\n",
        "\n",
        "# setup the coefficient value of regularization term.\n",
        "lll_lambda=100\n",
        "ewc_acc= []\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "prev_guards = []\n",
        "\n",
        "# iterate training on each task continually.\n",
        "for train_indexes in task_bar:\n",
        "  # Train Each Task\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  \n",
        "  # get model weight and calculate guidance for each weight\n",
        "  prev_guards.append(lll_object._precision_matrices)\n",
        "  lll_object=ewc(model=model, dataloader=train_dataloaders[train_indexes], device=device, prev_guards=prev_guards)\n",
        "\n",
        "  # new a Optimizer\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "  # collect average accuracy in each epoch\n",
        "  ewc_acc.extend(acc_list)\n",
        "\n",
        "  # Update tqdm displayer\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch!     \n",
        "print(ewc_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "cVcXQ2ztJHIq"
      },
      "source": [
        "### MAS\n",
        "Memory Aware Synapses\n",
        "\n",
        "The mas class applied MAS algorithm to calculate the regularization term.\n",
        "\n",
        "The concept of MAS is similar to EWC, the only difference is the calculation of the important weight. \n",
        "The details are mentioned in the following blocks.\n",
        "\n",
        "MAS:\n",
        "\n",
        "In MAS, the Loss function is shown below, the model learns task A before it learned task B.\n",
        "\n",
        "$$\\mathcal{L}_B = \\mathcal{L}(\\theta) + \\sum_{i} \\frac{\\lambda}{2} \\Omega_i (\\theta_{i} - \\theta_{A,i}^{*})^2$$\n",
        "\n",
        "Compare with EWC, the $F_i$ in the loss function is replaced with $\\Omega_i$ in the following function.\n",
        "\n",
        "$$\\Omega_i = || \\frac{\\partial \\ell_2^2(M(x_k; \\theta))}{\\partial \\theta_i} || $$ \n",
        "\n",
        "$x_k$ is the sample data of the previous task. So the $\\Omega$ is obtained gradients of the squared L2-norm of the learned network output.\n",
        "\n",
        "The method proposed in the paper is the local version by taking squared L2-norm outputs from each layer of the model.\n",
        "\n",
        "Here we only want you to implement the global version by taking outputs from the last layer of the model.\n",
        "\n",
        "For Your Information: \n",
        "[Memory Aware Synapses](https://arxiv.org/pdf/1711.09601.pdf)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9lKFEzSLJNBX"
      },
      "outputs": [],
      "source": [
        "class mas(object):\n",
        "  \"\"\"\n",
        "  @article{aljundi2017memory,\n",
        "      title={Memory Aware Synapses: Learning what (not) to forget},\n",
        "      author={Aljundi, Rahaf and Babiloni, Francesca and Elhoseiny, Mohamed and Rohrbach, Marcus and Tuytelaars, Tinne},\n",
        "      booktitle={ECCV},\n",
        "      year={2018},\n",
        "      url={https://eccv2018.org/openaccess/content_ECCV_2018/papers/Rahaf_Aljundi_Memory_Aware_Synapses_ECCV_2018_paper.pdf}\n",
        "  }\n",
        "  \"\"\"\n",
        "  def __init__(self, model: nn.Module, dataloader, device, prev_guards=[None]):\n",
        "    self.model = model \n",
        "    self.dataloader = dataloader\n",
        "    # extract all parameters in models\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad} \n",
        "    \n",
        "    # initialize parameters\n",
        "    self.p_old = {} \n",
        "    \n",
        "    self.device = device\n",
        "\n",
        "    # save previous guards\n",
        "    self.previous_guards_list = prev_guards\n",
        "    \n",
        "    # generate Omega(Ω) matrix for MAS\n",
        "    self._precision_matrices = self.calculate_importance() \n",
        "\n",
        "    # keep the old parameter in self.p_old\n",
        "    for n, p in self.params.items():\n",
        "      self.p_old[n] = p.clone().detach() \n",
        "  \n",
        "  def calculate_importance(self):\n",
        "    precision_matrices = {}\n",
        "    # initialize Omega(Ω) matrix（all filled zero）\n",
        "    for n, p in self.params.items():\n",
        "      precision_matrices[n] = p.clone().detach().fill_(0) \n",
        "      for i in range(len(self.previous_guards_list)):\n",
        "        if self.previous_guards_list[i]:\n",
        "          precision_matrices[n] += self.previous_guards_list[i][n]\n",
        "\n",
        "    self.model.eval()\n",
        "    if self.dataloader is not None:\n",
        "      num_data = len(self.dataloader)\n",
        "      for data in self.dataloader:\n",
        "        self.model.zero_grad()\n",
        "        output = self.model(data[0].to(self.device))\n",
        "        ################################################################\n",
        "        #####  TODO: generate Omega(Ω) matrix for MAS.  #####   \n",
        "        ################################################################\n",
        "        pass   \n",
        "        ################################################################                  \n",
        "    \n",
        "      precision_matrices = {n: p for n, p in precision_matrices.items()}\n",
        "    return precision_matrices\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0\n",
        "    for n, p in model.named_parameters():\n",
        "      _loss = self._precision_matrices[n] * (p - self.p_old[n]) ** 2\n",
        "      loss += _loss.sum()\n",
        "    return loss\n",
        "\n",
        "  def update(self, model):\n",
        "    # do nothing\n",
        "    return "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "wn1VGt38KSG-"
      },
      "outputs": [],
      "source": [
        "# MAS\n",
        "print(\"RUN MAS\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "lll_object=mas(model=model, dataloader=None, device=device)\n",
        "lll_lambda=0.1\n",
        "mas_acc= []\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "prev_guards = []\n",
        "\n",
        "for train_indexes in task_bar:\n",
        "  # Train Each Task\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  \n",
        "  # get model weight and calculate guidance for each weight\n",
        "  prev_guards.append(lll_object._precision_matrices)\n",
        "  lll_object=mas(model=model, dataloader=train_dataloaders[train_indexes], device=device, prev_guards=prev_guards)\n",
        "\n",
        "  # New a Optimizer\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "  # Collect average accuracy in each epoch\n",
        "  mas_acc.extend(acc_list)\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch!     \n",
        "print(mas_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "oI-iLmEZKoWH"
      },
      "source": [
        "### SI\n",
        "The si class applied SI (Synaptic Intelligence) algorithm to calculate the regularization term."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_rXpQIv8Kvsb"
      },
      "outputs": [],
      "source": [
        "# SI\n",
        "class si(object):\n",
        "  \"\"\"\n",
        "  @article{kirkpatrick2017overcoming,\n",
        "      title={Overcoming catastrophic forgetting in neural networks},\n",
        "      author={Kirkpatrick, James and Pascanu, Razvan and Rabinowitz, Neil and Veness, Joel and Desjardins, Guillaume and Rusu, Andrei A and Milan, Kieran and Quan, John and Ramalho, Tiago and Grabska-Barwinska, Agnieszka and others},\n",
        "      journal={Proceedings of the national academy of sciences},\n",
        "      year={2017},\n",
        "      url={https://arxiv.org/abs/1612.00796}\n",
        "  }\n",
        "  \"\"\"\n",
        "  def __init__(self, model, dataloader, epsilon, device):\n",
        "    self.model = model\n",
        "    self.dataloader = dataloader\n",
        "    self.device = device\n",
        "    self.epsilon = epsilon\n",
        "    # extract all parameters in models\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad}\n",
        "    \n",
        "    self._n_p_prev, self._n_omega = self._calculate_importance() \n",
        "    self.W, self.p_old = self._init_()\n",
        "    \n",
        "\n",
        "  def _init_(self):\n",
        "    W = {}\n",
        "    p_old = {}\n",
        "    for n, p in self.model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        W[n] = p.data.clone().zero_()\n",
        "        p_old[n] = p.data.clone()\n",
        "    return W, p_old\n",
        "\n",
        "  def _calculate_importance(self):\n",
        "    n_p_prev = {}\n",
        "    n_omega = {}\n",
        "\n",
        "    if self.dataloader != None:\n",
        "      for n, p in self.model.named_parameters():\n",
        "        n = n.replace('.', '__')\n",
        "        if p.requires_grad:\n",
        "          # Find/calculate new values for quadratic penalty on parameters\n",
        "          p_prev = getattr(self.model, '{}_SI_prev_task'.format(n))\n",
        "          W = getattr(self.model, '{}_W'.format(n))\n",
        "          p_current = p.detach().clone()\n",
        "          p_change = p_current - p_prev\n",
        "          omega_add = W/(p_change**2 + self.epsilon)\n",
        "          try:\n",
        "            omega = getattr(self.model, '{}_SI_omega'.format(n))\n",
        "          except AttributeError:\n",
        "            omega = p.detach().clone().zero_()\n",
        "          omega_new = omega + omega_add\n",
        "          n_omega[n] = omega_new\n",
        "          n_p_prev[n] = p_current\n",
        "\n",
        "          # Store these new values in the model\n",
        "          self.model.register_buffer('{}_SI_prev_task'.format(n), p_current)\n",
        "          self.model.register_buffer('{}_SI_omega'.format(n), omega_new)\n",
        "\n",
        "    else:\n",
        "      for n, p in self.model.named_parameters():\n",
        "        n = n.replace('.', '__')\n",
        "        if p.requires_grad:\n",
        "          n_p_prev[n] = p.detach().clone()\n",
        "          n_omega[n] = p.detach().clone().zero_()\n",
        "          self.model.register_buffer('{}_SI_prev_task'.format(n), p.detach().clone())\n",
        "    return n_p_prev, n_omega\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0.0\n",
        "    for n, p in model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        prev_values = self._n_p_prev[n]\n",
        "        omega = self._n_omega[n]\n",
        "        _loss = omega * (p - prev_values) ** 2\n",
        "        loss += _loss.sum()\n",
        "    return loss\n",
        "  \n",
        "  def update(self, model):\n",
        "    for n, p in model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        if p.grad is not None:\n",
        "          self.W[n].add_(-p.grad * (p.detach() - self.p_old[n]))\n",
        "          self.model.register_buffer('{}_W'.format(n), self.W[n])\n",
        "        self.p_old[n] = p.detach().clone()\n",
        "    return "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-OH6OsfOU8Ac"
      },
      "outputs": [],
      "source": [
        "# SI\n",
        "print(\"RUN SI\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "lll_object=si(model=model, dataloader=None, epsilon=0.1, device=device)\n",
        "lll_lambda=1\n",
        "si_acc = []\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "\n",
        "for train_indexes in task_bar:\n",
        "  # Train Each Task\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  \n",
        "  # get model weight and calculate guidance for each weight\n",
        "  lll_object=si(model=model, dataloader=train_dataloaders[train_indexes], epsilon=0.1, device=device)\n",
        "\n",
        "  # New a Optimizer\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "  # Collect average accuracy in each epoch\n",
        "  si_acc.extend(acc_list)\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch!     \n",
        "print(si_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "B6Y661vxVOHQ"
      },
      "source": [
        "### RWalk\n",
        "\n",
        "#### Remanian Walk for Incremental Learning\n",
        "\n",
        "The rwalk class applied Remanian Walk algorithm to calculate the regularization term.\n",
        "\n",
        "The details are mentioned in the following blocks."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "gUFOqSFeVYwT"
      },
      "outputs": [],
      "source": [
        "class rwalk(object):\n",
        "  def __init__(self, model, dataloader, epsilon, device, prev_guards=[None]):\n",
        "    self.model = model\n",
        "    self.dataloader = dataloader\n",
        "    self.device = device\n",
        "    self.epsilon = epsilon\n",
        "    self.update_ewc_parameter = 0.4\n",
        "    # extract model parameters and store in dictionary\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad}\n",
        "    \n",
        "    # initialize the guidance matrix\n",
        "    self._means = {} \n",
        "\n",
        "    self.previous_guards_list = prev_guards\n",
        "    \n",
        "    # Generate Fisher (F) Information Matrix\n",
        "    self._precision_matrices = self._calculate_importance_ewc()\n",
        "      \n",
        "    self._n_p_prev, self._n_omega = self._calculate_importance() \n",
        "    self.W, self.p_old = self._init_()\n",
        "\n",
        "  def _init_(self):\n",
        "    W = {}\n",
        "    p_old = {}\n",
        "    for n, p in self.model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        W[n] = p.data.clone().zero_()\n",
        "        p_old[n] = p.data.clone()\n",
        "    return W, p_old\n",
        "\n",
        "  def _calculate_importance(self):\n",
        "    n_p_prev = {}\n",
        "    n_omega = {}\n",
        "\n",
        "    if self.dataloader is not None:\n",
        "      for n, p in self.model.named_parameters():\n",
        "        n = n.replace('.', '__')\n",
        "        if p.requires_grad:\n",
        "          # Find/calculate new values for quadratic penalty on parameters\n",
        "          p_prev = getattr(self.model, '{}_SI_prev_task'.format(n))\n",
        "          W = getattr(self.model, '{}_W'.format(n))\n",
        "          p_current = p.detach().clone()\n",
        "          p_change = p_current - p_prev\n",
        "          omega_add = W / (1.0 / 2.0*self._precision_matrices[n] *p_change**2 + self.epsilon)\n",
        "          try:\n",
        "              omega = getattr(self.model, '{}_SI_omega'.format(n))\n",
        "          except AttributeError:\n",
        "              omega = p.detach().clone().zero_()\n",
        "          omega_new = 0.5 * omega + 0.5 *omega_add\n",
        "          n_omega[n] = omega_new\n",
        "          n_p_prev[n] = p_current\n",
        "\n",
        "          # Store these new values in the model\n",
        "          self.model.register_buffer('{}_SI_prev_task'.format(n), p_current)\n",
        "          self.model.register_buffer('{}_SI_omega'.format(n), omega_new)\n",
        "\n",
        "    else:\n",
        "      for n, p in self.model.named_parameters():\n",
        "        n = n.replace('.', '__')\n",
        "        if p.requires_grad:\n",
        "          n_p_prev[n] = p.detach().clone()\n",
        "          n_omega[n] = p.detach().clone().zero_()\n",
        "          self.model.register_buffer('{}_SI_prev_task'.format(n), p.detach().clone())\n",
        "    return n_p_prev, n_omega\n",
        "  \n",
        "  def _calculate_importance_ewc(self):\n",
        "    precision_matrices = {}\n",
        "    for n, p in self.params.items():\n",
        "      # initialize Fisher (F) matrix（all fill zero） \n",
        "      n = n.replace('.', '__') \n",
        "      precision_matrices[n] = p.clone().detach().fill_(0)\n",
        "      for i in range(len(self.previous_guards_list)):\n",
        "        if self.previous_guards_list[i]:\n",
        "          precision_matrices[n] += self.previous_guards_list[i][n]\n",
        "           \n",
        "\n",
        "    self.model.eval()\n",
        "    if self.dataloader is not None:\n",
        "      number_data = len(self.dataloader)\n",
        "      for n, p in self.model.named_parameters():                         \n",
        "        n = n.replace('.', '__')\n",
        "        precision_matrices[n].data *= (1 - self.update_ewc_parameter)\n",
        "      for data in self.dataloader:\n",
        "        self.model.zero_grad()\n",
        "        input = data[0].to(self.device)\n",
        "        output = self.model(input)\n",
        "        label = data[1].to(self.device)\n",
        "\n",
        "        # generate Fisher(F) matrix for RWALK    \n",
        "        loss = F.nll_loss(F.log_softmax(output, dim=1), label) \n",
        "        loss.backward()                                                    \n",
        "                                                                          \n",
        "        for n, p in self.model.named_parameters():                         \n",
        "          n = n.replace('.', '__')\n",
        "          precision_matrices[n].data += self.update_ewc_parameter*p.grad.data ** 2 / number_data  \n",
        "                                                                  \n",
        "      precision_matrices = {n: p for n, p in precision_matrices.items()}\n",
        "    return precision_matrices\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0.0\n",
        "    for n, p in model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        prev_values = self._n_p_prev[n]\n",
        "        omega = self._n_omega[n]\n",
        "        # Generate regularization term  _loss by omega and Fisher Matrix\n",
        "        _loss = (omega + self._precision_matrices[n]) * (p - prev_values) ** 2\n",
        "        loss += _loss.sum()\n",
        "\n",
        "    return loss\n",
        "  \n",
        "  def update(self, model):\n",
        "    for n, p in model.named_parameters():\n",
        "      n = n.replace('.', '__')\n",
        "      if p.requires_grad:\n",
        "        if p.grad is not None:\n",
        "          self.W[n].add_(-p.grad * (p.detach() - self.p_old[n]))\n",
        "          self.model.register_buffer('{}_W'.format(n), self.W[n])\n",
        "        self.p_old[n] = p.detach().clone()\n",
        "    return "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "E6wH-Nc2XgJY"
      },
      "outputs": [],
      "source": [
        "# RWalk\n",
        "print(\"RUN Rwalk\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "lll_object=rwalk(model=model, dataloader=None, epsilon=0.1, device=device)\n",
        "lll_lambda=100\n",
        "rwalk_acc = []\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "prev_guards = []\n",
        "\n",
        "for train_indexes in task_bar:\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  prev_guards.append(lll_object._precision_matrices)\n",
        "  lll_object=rwalk(model=model, dataloader=train_dataloaders[train_indexes], epsilon=0.1, device=device, prev_guards=prev_guards)\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "  rwalk_acc.extend(acc_list)\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch!     \n",
        "print(rwalk_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "d0mm4MhmXnti"
      },
      "source": [
        "### SCP\n",
        "Sliced Cramer Preservation\n",
        "\n",
        "Pseudo Code:\n",
        "<img src=\"https://i.ibb.co/QJycmNZ/2021-02-18-21-07.png\" width=\"100%\">"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "71W75eFhXvrB"
      },
      "outputs": [],
      "source": [
        "def sample_spherical(npoints, ndim=3):\n",
        "  vec = np.random.randn(ndim, npoints)\n",
        "  vec /= np.linalg.norm(vec, axis=0)\n",
        "  return torch.from_numpy(vec)\n",
        "\n",
        "class scp(object):\n",
        "  \"\"\"\n",
        "  OPEN REVIEW VERSION:\n",
        "  https://openreview.net/forum?id=BJge3TNKwH\n",
        "  \"\"\"\n",
        "  def __init__(self, model: nn.Module, dataloader, L: int, device, prev_guards=[None]):\n",
        "    self.model = model \n",
        "    self.dataloader = dataloader\n",
        "    self.params = {n: p for n, p in self.model.named_parameters() if p.requires_grad}\n",
        "    self._state_parameters = {}\n",
        "    self.L= L\n",
        "    self.device = device\n",
        "    self.previous_guards_list = prev_guards\n",
        "    self._precision_matrices = self.calculate_importance()\n",
        "    for n, p in self.params.items():\n",
        "      self._state_parameters[n] = p.clone().detach()\n",
        "  \n",
        "  def calculate_importance(self):\n",
        "    precision_matrices = {}\n",
        "    for n, p in self.params.items():\n",
        "      precision_matrices[n] = p.clone().detach().fill_(0)\n",
        "      for i in range(len(self.previous_guards_list)):\n",
        "        if self.previous_guards_list[i]:\n",
        "          precision_matrices[n] += self.previous_guards_list[i][n]\n",
        "\n",
        "    self.model.eval()\n",
        "    if self.dataloader is not None:\n",
        "      num_data = len(self.dataloader)\n",
        "      for data in self.dataloader:\n",
        "        self.model.zero_grad()\n",
        "        output = self.model(data[0].to(self.device))\n",
        "          \n",
        "        mean_vec = output.mean(dim=0)\n",
        "\n",
        "        L_vectors = sample_spherical(self.L, output.shape[-1])\n",
        "        L_vectors = L_vectors.transpose(1,0).to(self.device).float()\n",
        "                    \n",
        "        total_scalar = 0\n",
        "        for vec in L_vectors:\n",
        "          scalar=torch.matmul(vec, mean_vec)\n",
        "          total_scalar += scalar\n",
        "        total_scalar /= L_vectors.shape[0] \n",
        "        total_scalar.backward()     \n",
        "\n",
        "        for n, p in self.model.named_parameters():                      \n",
        "          precision_matrices[n].data += p.grad**2 / num_data      \n",
        "              \n",
        "    precision_matrices = {n: p for n, p in precision_matrices.items()}\n",
        "    return precision_matrices\n",
        "\n",
        "  def penalty(self, model: nn.Module):\n",
        "    loss = 0\n",
        "    for n, p in model.named_parameters():\n",
        "      _loss = self._precision_matrices[n] * (p - self._state_parameters[n]) ** 2\n",
        "      loss += _loss.sum()\n",
        "    return loss\n",
        "  \n",
        "  def update(self, model):\n",
        "    # do nothing\n",
        "    return "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "m6svVnP3aiIG"
      },
      "outputs": [],
      "source": [
        "# SCP\n",
        "print(\"RUN SLICE CRAMER PRESERVATION\")\n",
        "model = Model()\n",
        "model = model.to(device)\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "\n",
        "lll_object=scp(model=model, dataloader=None, L=100, device=device)\n",
        "lll_lambda=100\n",
        "scp_acc= []\n",
        "task_bar = tqdm.auto.trange(len(train_dataloaders),desc=\"Task   1\")\n",
        "prev_guards = []\n",
        "\n",
        "for train_indexes in task_bar:\n",
        "  model, _, acc_list = train(model, optimizer, train_dataloaders[train_indexes], args.epochs_per_task, lll_object, lll_lambda, evaluate=evaluate,device=device, test_dataloaders=test_dataloaders[:train_indexes+1])\n",
        "  prev_guards.append(lll_object._precision_matrices)\n",
        "  lll_object=scp(model=model, dataloader=train_dataloaders[train_indexes], L=100, device=device, prev_guards=prev_guards)\n",
        "  optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)\n",
        "  scp_acc.extend(acc_list)\n",
        "  task_bar.set_description_str(f\"Task  {train_indexes+2:2}\")\n",
        "\n",
        "# average accuracy in each task per epoch!     \n",
        "print(scp_acc)\n",
        "print(\"==================================================================================================\")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Plot function"
      ],
      "metadata": {
        "id": "VNMGpoyhq4QQ"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import matplotlib.pyplot as plt\n",
        "def draw_acc(acc_list, label_list):\n",
        "  for acc, label in zip(acc_list, label_list):\n",
        "    plt.plot(acc, marker='o', lineStyle='--', linewidth=2, markersize=4, label=label)\n",
        "    plt.legend()\n",
        "  plt.savefig('acc_summary.png')\n",
        "  plt.show() \n",
        "\n",
        "acc_list = [baseline_acc, ewc_acc, mas_acc, si_acc, rwalk_acc, scp_acc]\n",
        "label_list = ['baseline', 'EWC', 'MAS', 'SI', 'RWALK', 'SCP']\n",
        "draw_acc(acc_list, label_list)"
      ],
      "metadata": {
        "id": "6oiXbZgxq59j"
      },
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "name": "ML2022Spring - HW14.ipynb",
      "provenance": [],
      "collapsed_sections": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    },
    "widgets": {
      "application/vnd.jupyter.widget-state+json": {
        "6678e54bfcce4aaa80134cf29d543bce": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_d6b498ee01f74b12a51dc944e633c304",
              "IPY_MODEL_e4c801c7dea848b8b392808ba94acc07",
              "IPY_MODEL_954f009683e34fa2871775d8eebea8ba"
            ],
            "layout": "IPY_MODEL_afe49763962c4bc293ba8692feaf8078"
          }
        },
        "d6b498ee01f74b12a51dc944e633c304": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_7c9171136dcc426baaddb573f587a200",
            "placeholder": "​",
            "style": "IPY_MODEL_74e98976de5b465a8218a4f5398d89ee",
            "value": ""
          }
        },
        "e4c801c7dea848b8b392808ba94acc07": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_3c57de7448674f718a2c12f7a8a3dc73",
            "max": 9912422,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_bd3b7a2948c6460db33ecebebacb3e6e",
            "value": 9912422
          }
        },
        "954f009683e34fa2871775d8eebea8ba": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_262e84a4c30448a89f9a4fcb09d718d4",
            "placeholder": "​",
            "style": "IPY_MODEL_342d7362bdc242919b28d8d389b5ed2c",
            "value": " 9913344/? [00:00&lt;00:00, 6498309.37it/s]"
          }
        },
        "afe49763962c4bc293ba8692feaf8078": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "7c9171136dcc426baaddb573f587a200": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "74e98976de5b465a8218a4f5398d89ee": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "3c57de7448674f718a2c12f7a8a3dc73": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "bd3b7a2948c6460db33ecebebacb3e6e": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "262e84a4c30448a89f9a4fcb09d718d4": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "342d7362bdc242919b28d8d389b5ed2c": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "5bf7bd4c4ac047b382f0d85a558704b1": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_557c67df0db540a0b0597d1ba64fe2c7",
              "IPY_MODEL_a863f04a60404ece8e3492705d56082d",
              "IPY_MODEL_019c9ffd1526488887944f9d3d3ac559"
            ],
            "layout": "IPY_MODEL_21bf55b0dad04eb3baa460994dfffa2e"
          }
        },
        "557c67df0db540a0b0597d1ba64fe2c7": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_d71a16db1bd043cba776108b5b2024a5",
            "placeholder": "​",
            "style": "IPY_MODEL_bb2e25bff7c84ab0b613b9bfa4d9a3bf",
            "value": ""
          }
        },
        "a863f04a60404ece8e3492705d56082d": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_6bfe7158ed774e70ab3e93c985208b02",
            "max": 28881,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_a3a8cdd6807d4c2c90af0cfb1708fefb",
            "value": 28881
          }
        },
        "019c9ffd1526488887944f9d3d3ac559": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_ed01d150ab1946b9b26ebfc1028ce74c",
            "placeholder": "​",
            "style": "IPY_MODEL_8059df5c69ad48af8627f7bae3cb1c14",
            "value": " 29696/? [00:00&lt;00:00, 841837.39it/s]"
          }
        },
        "21bf55b0dad04eb3baa460994dfffa2e": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "d71a16db1bd043cba776108b5b2024a5": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "bb2e25bff7c84ab0b613b9bfa4d9a3bf": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "6bfe7158ed774e70ab3e93c985208b02": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "a3a8cdd6807d4c2c90af0cfb1708fefb": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "ed01d150ab1946b9b26ebfc1028ce74c": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "8059df5c69ad48af8627f7bae3cb1c14": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "49683c778d6d4b2b8eef56ff767d1a5f": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_cd204aebd36c4a51b9a3e076813c22f5",
              "IPY_MODEL_a4b5d00ba1394ee3a84a6b0482392250",
              "IPY_MODEL_9574e0c85a9b4fbc8d5688297e75c4de"
            ],
            "layout": "IPY_MODEL_b73534bd79204873a0363689e54546c1"
          }
        },
        "cd204aebd36c4a51b9a3e076813c22f5": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_bbf27d4324d84ea182524b00685141bc",
            "placeholder": "​",
            "style": "IPY_MODEL_b53d43d75e34457fab24ee729e816c2b",
            "value": ""
          }
        },
        "a4b5d00ba1394ee3a84a6b0482392250": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_489df34a47d64f5e8069c06d26d1e9cc",
            "max": 1648877,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_cb1dd9f39ad543698a883694d737d62d",
            "value": 1648877
          }
        },
        "9574e0c85a9b4fbc8d5688297e75c4de": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_adb1230c890a4d099c71ef949c3933a5",
            "placeholder": "​",
            "style": "IPY_MODEL_9e3719f2f271462e98808d4aa595e3db",
            "value": " 1649664/? [00:00&lt;00:00, 7067612.98it/s]"
          }
        },
        "b73534bd79204873a0363689e54546c1": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "bbf27d4324d84ea182524b00685141bc": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "b53d43d75e34457fab24ee729e816c2b": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "489df34a47d64f5e8069c06d26d1e9cc": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "cb1dd9f39ad543698a883694d737d62d": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "adb1230c890a4d099c71ef949c3933a5": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "9e3719f2f271462e98808d4aa595e3db": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "4c0f433640d84267ad7d429eba7822a9": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HBoxModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HBoxModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HBoxView",
            "box_style": "",
            "children": [
              "IPY_MODEL_e508442a7aa34b358b9970ae313a26f8",
              "IPY_MODEL_a52e3522bb854861a370e5ddf6f52bc2",
              "IPY_MODEL_87a4cd167a794115998e6505f6dabc44"
            ],
            "layout": "IPY_MODEL_8c77c242a7c1474b9e2758291c57dd44"
          }
        },
        "e508442a7aa34b358b9970ae313a26f8": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_9514e4e67c7b4ac28bd4e0f513027d9f",
            "placeholder": "​",
            "style": "IPY_MODEL_5cea3374e02547308903a5b30776911b",
            "value": ""
          }
        },
        "a52e3522bb854861a370e5ddf6f52bc2": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "FloatProgressModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "FloatProgressModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "ProgressView",
            "bar_style": "success",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_74232ccdd40247378f4173e6bd6d306e",
            "max": 4542,
            "min": 0,
            "orientation": "horizontal",
            "style": "IPY_MODEL_71ecc787a84641b1ae638ca713d61ffc",
            "value": 4542
          }
        },
        "87a4cd167a794115998e6505f6dabc44": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "HTMLModel",
          "model_module_version": "1.5.0",
          "state": {
            "_dom_classes": [],
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "HTMLModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/controls",
            "_view_module_version": "1.5.0",
            "_view_name": "HTMLView",
            "description": "",
            "description_tooltip": null,
            "layout": "IPY_MODEL_988647e20dbd45d9b6dfce4a7a06ffbd",
            "placeholder": "​",
            "style": "IPY_MODEL_fead6467c43340a48571fa8d5f3d61d1",
            "value": " 5120/? [00:00&lt;00:00, 182379.63it/s]"
          }
        },
        "8c77c242a7c1474b9e2758291c57dd44": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "9514e4e67c7b4ac28bd4e0f513027d9f": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "5cea3374e02547308903a5b30776911b": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        },
        "74232ccdd40247378f4173e6bd6d306e": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "71ecc787a84641b1ae638ca713d61ffc": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "ProgressStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "ProgressStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "bar_color": null,
            "description_width": ""
          }
        },
        "988647e20dbd45d9b6dfce4a7a06ffbd": {
          "model_module": "@jupyter-widgets/base",
          "model_name": "LayoutModel",
          "model_module_version": "1.2.0",
          "state": {
            "_model_module": "@jupyter-widgets/base",
            "_model_module_version": "1.2.0",
            "_model_name": "LayoutModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "LayoutView",
            "align_content": null,
            "align_items": null,
            "align_self": null,
            "border": null,
            "bottom": null,
            "display": null,
            "flex": null,
            "flex_flow": null,
            "grid_area": null,
            "grid_auto_columns": null,
            "grid_auto_flow": null,
            "grid_auto_rows": null,
            "grid_column": null,
            "grid_gap": null,
            "grid_row": null,
            "grid_template_areas": null,
            "grid_template_columns": null,
            "grid_template_rows": null,
            "height": null,
            "justify_content": null,
            "justify_items": null,
            "left": null,
            "margin": null,
            "max_height": null,
            "max_width": null,
            "min_height": null,
            "min_width": null,
            "object_fit": null,
            "object_position": null,
            "order": null,
            "overflow": null,
            "overflow_x": null,
            "overflow_y": null,
            "padding": null,
            "right": null,
            "top": null,
            "visibility": null,
            "width": null
          }
        },
        "fead6467c43340a48571fa8d5f3d61d1": {
          "model_module": "@jupyter-widgets/controls",
          "model_name": "DescriptionStyleModel",
          "model_module_version": "1.5.0",
          "state": {
            "_model_module": "@jupyter-widgets/controls",
            "_model_module_version": "1.5.0",
            "_model_name": "DescriptionStyleModel",
            "_view_count": null,
            "_view_module": "@jupyter-widgets/base",
            "_view_module_version": "1.2.0",
            "_view_name": "StyleView",
            "description_width": ""
          }
        }
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}